| name | code-optimizer |
| description | Analyzes and optimizes code for better performance, memory usage, and efficiency. Use when code is slow, memory-intensive, or inefficient. Supports Python and Java optimization including execution speed improvements, memory reduction, database query optimization, and I/O efficiency. Provides before/after examples with detailed explanations of why optimizations work, complexity analysis, and measurable performance improvements. |
Code Optimizer
Improve code performance, memory usage, and efficiency through systematic optimization.
Core Capabilities
This skill helps optimize code by:
- Analyzing performance bottlenecks - Identifying slow or inefficient code
- Suggesting optimizations - Providing concrete improvements with examples
- Explaining trade-offs - Describing benefits and potential drawbacks
- Measuring impact - Estimating performance gains
- Preserving correctness - Ensuring optimizations don't change behavior
Optimization Workflow
Step 1: Identify Optimization Opportunities
Analyze code to find performance bottlenecks.
Look for:
- Nested loops (O(n²) or worse complexity)
- Repeated expensive operations
- Inefficient data structures
- Unnecessary object creation
- Database N+1 queries
- Blocking I/O operations
- Memory leaks or excessive allocation
Quick Analysis Questions:
- What is the time complexity? Can it be reduced?
- Are there repeated calculations that could be cached?
- Is the right data structure being used?
- Are there unnecessary copies or allocations?
- Can operations be batched or parallelized?
Step 2: Categorize the Optimization
Determine the type of optimization needed.
Execution Speed:
- Algorithm optimization (better complexity)
- Loop optimization
- Caching/memoization
- Lazy evaluation
- Parallel processing
Memory Usage:
- Reduce object creation
- Use generators/streams instead of lists
- Clear references to enable garbage collection
- Use appropriate data structures
- Avoid memory leaks
Database Operations:
- Query optimization (indexes, joins)
- Batch operations
- Connection pooling
- Caching
- Reduce round trips
I/O Operations:
- Buffering
- Async/non-blocking I/O
- Batch requests
- Compression
- Caching
Step 3: Propose Optimization with Examples
Provide before/after code with clear explanations.
Optimization Template:
## Optimization: [Brief Description]
### Before (Inefficient)
```[language]
[original code]
Issues:
- Issue 1: [Problem description]
- Issue 2: [Problem description]
Complexity: O([complexity])
Performance: [estimated time/memory]
After (Optimized)
[optimized code]
Improvements:
- Improvement 1: [What changed]
- Improvement 2: [What changed]
Complexity: O([new complexity])
Performance: [estimated time/memory]
Gain: [X% faster / Y% less memory]
Why This Works
[Detailed explanation of the optimization]
Trade-offs
Pros:
Cons:
- [Drawback 1, if any]
- [Drawback 2, if any]
When to Use
- Use when: [scenario]
- Avoid when: [scenario]
### Step 4: Measure and Validate
Ensure optimization actually improves performance.
**Measurement Techniques:**
**Python:**
```python
import time
import memory_profiler
# Time measurement
start = time.time()
result = function()
elapsed = time.time() - start
print(f"Elapsed: {elapsed:.4f}s")
# Memory measurement
from memory_profiler import profile
@profile
def function():
# Code to profile
pass
Java:
long start = System.nanoTime();
result = function();
long elapsed = System.nanoTime() - start;
System.out.println("Elapsed: " + elapsed / 1_000_000 + "ms");
Runtime runtime = Runtime.getRuntime();
long before = runtime.totalMemory() - runtime.freeMemory();
result = function();
long after = runtime.totalMemory() - runtime.freeMemory();
System.out.println("Memory used: " + (after - before) / 1024 + "KB");
Validation Checklist:
- ✓ Correctness: Output matches original
- ✓ Performance: Measurable improvement
- ✓ Memory: Reduced allocation or leaks fixed
- ✓ Maintainability: Code remains readable
- ✓ Edge cases: Handles all inputs correctly
Common Optimizations
Python Optimizations
1. Use List Comprehensions Over Loops
numbers = []
for i in range(1000):
if i % 2 == 0:
numbers.append(i * 2)
numbers = [i * 2 for i in range(1000) if i % 2 == 0]
2. Use Generators for Large Sequences
def get_numbers(n):
result = []
for i in range(n):
result.append(i ** 2)
return result
numbers = get_numbers(1000000)
def get_numbers(n):
for i in range(n):
yield i ** 2
numbers = get_numbers(1000000)
3. Use Built-in Functions
total = 0
for num in numbers:
total += num
total = sum(numbers)
4. Avoid Repeated Lookups
for i in range(len(data)):
process(data[i])
for item in data:
process(item)
for i, item in enumerate(data):
process(item)
5. Use Sets for Membership Testing
items = [1, 2, 3, 4, 5, ...]
if x in items:
do_something()
items = {1, 2, 3, 4, 5, ...}
if x in items:
do_something()
See references/python_optimizations.md for comprehensive Python optimization patterns.
Java Optimizations
1. Use StringBuilder for String Concatenation
String result = "";
for (int i = 0; i < 1000; i++) {
result += i + ",";
}
StringBuilder result = new StringBuilder();
for (int i = 0; i < 1000; i++) {
result.append(i).append(",");
}
String output = result.toString();
2. Use Appropriate Collection Types
List<Integer> numbers = new ArrayList<>();
numbers.contains(42);
Set<Integer> numbers = new HashSet<>();
numbers.contains(42);
3. Avoid Unnecessary Object Creation
for (int i = 0; i < 1000; i++) {
String key = new String("key" + i);
map.put(key, value);
}
for (int i = 0; i < 1000; i++) {
String key = "key" + i;
map.put(key, value);
}
4. Use Primitive Collections
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 1000000; i++) {
numbers.add(i);
}
int[] numbers = new int[1000000];
for (int i = 0; i < 1000000; i++) {
numbers[i] = i;
}
TIntArrayList numbers = new TIntArrayList();
See references/java_optimizations.md for comprehensive Java optimization patterns.
Database Optimizations
1. Fix N+1 Query Problem
users = User.query.all()
for user in users:
posts = user.posts.all()
process(posts)
users = User.query.options(
joinedload(User.posts)
).all()
for user in users:
posts = user.posts
process(posts)
2. Add Indexes
SELECT * FROM users WHERE email = 'user@example.com';
CREATE INDEX idx_users_email ON users(email);
SELECT * FROM users WHERE email = 'user@example.com';
3. Batch Operations
for item in items:
db.execute("INSERT INTO table VALUES (?)", (item,))
db.commit()
db.executemany("INSERT INTO table VALUES (?)",
[(item,) for item in items])
db.commit()
See references/database_optimizations.md for comprehensive database optimization patterns.
I/O Optimizations
1. Use Buffered I/O
with open('file.txt', 'r') as f:
for line in f:
process(line.strip())
with open('file.txt', 'r', buffering=8192) as f:
for line in f:
process(line.strip())
2. Batch API Calls
for user_id in user_ids:
user = api.get_user(user_id)
process(user)
users = api.get_users_batch(user_ids)
for user in users:
process(user)
Optimization Process
1. Profile Before Optimizing
Python Profiling:
python -m cProfile -s cumulative script.py
pip install line_profiler
kernprof -l -v script.py
pip install memory_profiler
python -m memory_profiler script.py
Java Profiling:
jvisualvm
java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder \
-XX:StartFlightRecording=duration=60s,filename=recording.jfr \
MyApp
2. Focus on Hot Paths
Optimize the 20% of code that takes 80% of time.
Find Hot Paths:
- Profile to find slowest functions
- Measure actual execution time
- Focus on code executed frequently
- Ignore code executed rarely
3. Measure Impact
Compare before and after:
import timeit
before = timeit.timeit(
'old_function(data)',
setup='from module import old_function, data',
number=1000
)
after = timeit.timeit(
'new_function(data)',
setup='from module import new_function, data',
number=1000
)
improvement = (before - after) / before * 100
print(f"Improvement: {improvement:.1f}%")
4. Maintain Readability
Don't sacrifice code clarity for minor gains.
Good Optimization:
users = [u for u in all_users if u.is_active]
Bad Optimization:
users = list(filter(lambda u: u.is_active, all_users))
Best Practices
- Profile first - Don't guess, measure
- Focus on bottlenecks - Optimize hot paths only
- Preserve correctness - Test thoroughly after optimizing
- Document trade-offs - Explain why optimization is worth it
- Measure improvements - Quantify performance gains
- Consider maintainability - Don't make code unreadable
- Use appropriate tools - Profilers, benchmarks, load tests
- Think about complexity - O(n²) to O(n log n) matters more than micro-optimizations
- Cache wisely - Balance memory vs. computation
- Avoid premature optimization - Optimize when proven necessary
Resources
references/python_optimizations.md - Comprehensive Python optimization techniques and patterns
references/java_optimizations.md - Comprehensive Java optimization techniques and patterns
references/database_optimizations.md - Database query and schema optimization strategies
Quick Reference
| Optimization Type | Python | Java | Impact |
|---|
| Algorithm complexity | Use better algorithm | Use better algorithm | High |
| Data structures | set/dict for lookup | HashMap/HashSet | High |
| String building | join() or f-strings | StringBuilder | High |
| Generators | yield | Stream API | Medium (memory) |
| Caching | @lru_cache | ConcurrentHashMap | Medium-High |
| Batching | Batch DB/API calls | Batch operations | High |
| Indexing | Use dict/set | Add DB indexes | High |
| Lazy evaluation | Generators | Streams/Suppliers | Medium |