Introduction
Performance optimization is a critical skill for any developer. Whether you're shipping a web application, a mobile app, or a data pipeline, slow code wastes money, degrades user experience, and increases infrastructure costs. Yet many engineers struggle to identify where the real bottlenecks lie. Profiling and targeted optimization are the keys, but they require the right questions to ask — both of your code and of the tools you use.
This article provides 10 ready-to-use prompts that you can copy, paste, and adapt. Each prompt is designed to guide an AI assistant (like ChatGPT, Claude, or a code review tool) toward a specific performance task: profiling, memory leaks, algorithmic improvements, caching, I/O reduction, database tuning, and more. Every prompt includes a concrete scenario, a usage example, and the type of code or output you can expect. Use them as a starting point for your own optimization workflow.
1. Profile & Identify Hotspots
Task: Ask the AI to analyze a codebase or snippet and find the most time-consuming functions.
Prompt:
“Analyze the following Python code and identify which functions are likely to be the hottest (most CPU time) based on algorithm complexity and nested loops. Suggest specific profiling tools (cProfile, py-spy, or line_profiler) and show how to run them. Output the top 3 candidate functions for optimization.”
Usage Example:
def process_data(items):
result = []
for i in range(len(items)):
for j in range(len(items)):
if items[i] > items[j]:
result.append(items[i] * items[j])
return result
Expected Output (abbreviated):
- The nested loop gives O(n²). Line_profiler would show the inner if and append as most time-consuming.
- Recommendation: replace with sorting or vectorized operations.
2. Spot Memory Leaks & High Allocation
Task: Detect excessive memory usage or objects that are not freed.
Prompt:
“Examine this Python class for possible memory leaks. Look for circular references, static lists that keep growing, or unclosed file handles. Suggest how to use
tracemallocorgcmodule to track allocations. Provide a modified version that fixes the leak.”
Usage Example:
class Cache:
def __init__(self):
self._store = {}
def add(self, key, value):
self._store[key] = value
Expected Output:
- If add is called infinitely, the dict grows unbounded. Add eviction policy (LRU) or use functools.lru_cache.
- Show code with @lru_cache(maxsize=128).
3. Reduce Algorithm Complexity (Big-O)
Task: Optimize a slow sort, search, or combinatorial function.
Prompt:
“The following function finds duplicates in a list. Current time complexity is O(n²). Rewrite it to run in O(n) or O(n log n) using a hash set or sorting. Explain the trade-offs in memory versus speed and show a benchmark with timeit.”
Usage Example:
def find_duplicates(arr):
dups = []
for i in range(len(arr)):
for j in range(i+1, len(arr)):
if arr[i] == arr[j] and arr[i] not in dups:
dups.append(arr[i])
return dups
Expected Output:
- Use set() for seen elements: seen = set(); dups = [x for x in arr if x in seen or seen.add(x)].
- Benchmark: O(n²) vs O(n) for 10,000 items — ~100 ms vs ~0.5 ms.
4. Parallelize CPU-bound Work
Task: Speed up a heavy computation by using multiple cores.
Prompt:
“Convert this single-threaded image filter (applied to 1000 files) to use Python’s
multiprocessing.Pool. Discuss the overhead of forking versus threading for I/O-bound tasks. Show a complete example withstarmapand timing comparison.”
Usage Example:
def apply_filter(image_path):
# heavy pixel manipulation
pass
if __name__ == '__main__':
images = ['img1.jpg', 'img2.jpg', ...]
for img in images:
apply_filter(img)
Expected Output:
- Use with Pool(4) as p: p.map(apply_filter, images).
- Measure wall time: 40s single-thread vs 12s parallel (4 cores).
5. Optimize I/O with Buffering & Batching
Task: Reduce disk or network read/write overhead.
Prompt:
“The script reads a large CSV file line by line with
readline(). This is slow due to many syscalls. Rewrite it to read in chunks (e.g., 64 KB buffer) usingpandas.read_csv(chunksize=10000)or rawopen(..., buffering=8192). Show a speed comparison with time and explain why buffering helps.”
Usage Example:
with open('big.csv') as f:
while line := f.readline():
process(line)
Expected Output:
- Replace with for chunk in pd.read_csv('big.csv', chunksize=10000): process(chunk).
- 10× speedup due to decreased context switches.
6. Add Caching to Avoid Recomputation
Task: Memoize expensive pure functions.
Prompt:
“The recursive Fibonacci implementation is O(2ⁿ). Add memoization using
functools.lru_cacheand compare runtime for n=35. Also discuss when not to cache (large input space, side effects).”
Usage Example:
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
Expected Output:
- Add @lru_cache(maxsize=None).
- Time for n=35: 5s → 0.0001s.
7. Optimize Database Queries (N+1 Problem)
Task: Avoid excessive SQL queries in ORMs.
Prompt:
“This Django view fetches a list of authors and their books. It suffers from the N+1 query problem. Show how to fix it using
select_relatedorprefetch_related. Include the raw SQL before and after, and explain database index usage.”
Usage Example:
def author_list(request):
authors = Author.objects.all()
for author in authors:
books = author.books.all() # N queries
...
Expected Output:
- Use Author.objects.prefetch_related('books').
- Before: 1 query for authors + N for books. After: 2 queries.
8. Reduce Network Roundtrips (API Calls)
Task: Batch multiple HTTP requests into one.
Prompt:
“This microservice sends one HTTP request per user to fetch their profile. For 1000 users, that’s 1000 requests. Rewrite it to use a batch endpoint (e.g.,
POST /profiles?ids=1,2,...) or useasynciowithaiohttpfor concurrent connections. Compare total latency.”
Usage Example:
for user_id in range(1000):
resp = requests.get(f'http://api/profile/{user_id}')
Expected Output:
- Use aiohttp.ClientSession with asyncio.gather. Latency drops from 1000×RTT to ~1×RTT + overhead.
9. Enable Compiler Optimizations (C/C++)
Task: Use proper compiler flags and restrict aliasing.
Prompt:
“The following C function runs slower than expected. Suggest compiler flags (
-O2,-march=native,-flto) and code changes like usingrestrictorinlineto help the compiler vectorize loops. Show the assembly differences or runtime improvement.”
Usage Example:
void add_arrays(int *a, int *b, int *c, int n) {
for (int i = 0; i < n; i++)
c[i] = a[i] + b[i];
}
Expected Output:
- Add -O3 -ffast-math -mavx2. With restrict, the compiler can use SIMD. Speedup 2-4×.
10. Precompute & Move Work Offline
Task: Shift computation from runtime to build/deploy time.
Prompt:
“A web page computes a large menu tree on every request. Suggest moving this to a background job that caches the result in Redis or a static JSON file. Write the cache-warming logic and show how to invalidate on changes. Estimate request time reduction.”
Usage Example:
def get_menu():
# heavy DB queries and recursion
return menu_tree
Expected Output:
- Cache in Redis with key menu:latest; set TTL or invalidate on update. Response time from 200ms to 2ms.
Conclusion
Code optimization is not about guessing — it’s about measuring and asking the right questions. The ten prompts above cover the most common performance antipatterns: inefficient algorithms, memory leaks, I/O overhead, and unnecessary computation. Use them as a checklist when you encounter slowness. Copy the prompt that matches your bottleneck, adapt it to your context, and let the AI help you generate both the diagnosis and the fix. Remember to always profile before optimizing and to benchmark after. If you found this guide useful, bookmark it and share it with your team — the next time someone says “it’s slow,” you’ll have the right prompt ready.
Comments