AI Coding Assistant Performance: Measure First, Fix Small
An AI coding assistant can suggest a faster version of your code in seconds. The trick is making sure the new version is actually faster. Measure first, change one thing at a time, and let the assistant help you prove the gain instead of guessing at it.
The problem: fast suggestions, slow code
An AI coding assistant can write a working function in seconds. That speed is useful, and it is also the trap. When the assistant rewrites a slow loop, adds caching, or parallelizes a task, the new code often looks faster. Looks are not evidence. Without a measurement before and after, you cannot tell whether you fixed the bottleneck, moved it somewhere else, added complexity, or made the code harder to read for no real gain.
Performance work rewards patience. The assistant works best as a fast pair programmer who can read a profile, suggest a small change, and help you test it. It is not an oracle that can declare code slow just by looking at it. Your job is to stay in charge of the evidence: what is slow, how slow it is, and what good enough means for this feature. A ten percent speedup on a task that runs once a day is rarely worth a rewrite. The same speedup on a request that runs a thousand times a minute can be worth a full day of work.
Measure first: a 30-minute profiling routine
Before you ask for any optimization, get a baseline. Pick one realistic workload: a real query, a real file, or a real user action. Time it, and record the number, the input size, and the environment. A vague report such as it feels slow gives the assistant nothing to work with, and it will guess. A concrete baseline gives both of you something to beat.
- Reproduce it. Run the slow path with realistic data, not a tiny toy example. Note the exact command or request and the time it takes.
- Profile it. Use your language profiler or a simple timer around the main steps. Find where the time actually goes before changing anything.
- Pick one hotspot. Fix the largest cost first. Optimizing the third-largest cost while the largest one stays untouched is a common way to do a lot of work for a small result.
- Set a target. Write down the number you want, such as under 200 milliseconds for this request, or half the current database queries. Stop when you reach it.
If you cannot reproduce the slowness, do not optimize yet. When slow code is also incorrect, fix the bug first, as in our guide to debugging Python with an AI coding assistant. A fast wrong answer is still wrong.
Give the assistant evidence, not just code
Most disappointing AI optimization suggestions come from thin context. The assistant sees a function, but not the profile, the data shape, the traffic pattern, or the constraints. Give it the evidence a senior colleague would ask for, in a short and focused form. Paste the profile summary, the function, the test that covers it, and the target. Leave out secrets, credentials, and huge data dumps. If a log or profile is long, paste the top ten lines and say what you cut.
A prompt that works
Ask for one change, not five. Ask for the trade-off in plain words. Ask what could break, and what test would catch it. That last question matters more than the code itself, because it forces the assistant to think about risk instead of only speed. Good logging helps here too: if you can see what the code did in production, you can give the assistant real traces instead of guesses. Our guide to observability and logging with AI coding assistants shows how to set that up without drowning in logs.
Turn slow code into small, testable changes
Once you know the hotspot, keep each change small enough to test on its own. Change one thing, rerun the same workload, and compare the same number. If two changes go in at once and the result improves, you will not know which one helped. If the result gets worse, you will not know which one to revert. Small steps feel slow. They are faster in the end, because they rarely need to be undone.
| Symptom | Likely cause | First fix to try | Verify with |
|---|---|---|---|
| Many small database queries | One query per item in a loop | Fetch in one batch, then map results | Query count and total time |
| Same work repeated | Expensive call inside a loop | Compute once, reuse the result | Profile before and after |
| Large response is slow | Too much data returned | Return only the fields the caller uses | Payload size and time |
| Waiting on other services | Requests run one after another | Run independent calls together, with a timeout | End-to-end time under load |
Keep the existing tests green, and add one test for the behavior you changed. If the change is a cache, test that stale data expires as expected. If the change batches queries, test the empty list and the large list, not only the happy path. Test automation with an AI coding assistant can help you generate those edge cases quickly, but read each generated test before you trust it. A test that passes for the wrong reason is worse than no test.
Traps that waste more time than they save
- Premature optimization: tuning code before you know it is slow. Profile first, or you will polish code nobody waits on.
- Micro-benchmarks that lie: a tiny loop in isolation can rank two approaches in the opposite order from real traffic. Always confirm with the real workload.
- Caching everything: a cache hides slowness and adds stale data, invalidation bugs, and memory pressure. Cache only after measuring, and only with a clear expiry rule.
- Parallelizing too early: threads and processes add complexity and new failure modes. They help when the work is truly independent and waiting, not when the real problem is a bad query.
- Trusting a generated benchmark: if the assistant writes the benchmark, check the inputs, the warm-up, and what is actually being timed. A benchmark that skips the slow part will flatter any change.
A reusable 30-minute workflow
Use this workflow whenever a feature feels slow. It works for a solo developer and for a small team, and it keeps the assistant useful without letting it drive.
- Minutes 0 to 10: measure. Reproduce the slow path, record the baseline, and profile it. Write the target down.
- Minutes 10 to 20: one change. Share the profile and ask for one fix with its trade-off. Apply it, run the tests, and rerun the same workload.
- Minutes 20 to 30: decide. If the gain meets the target and the tests pass, keep it and write a short note about what changed and why. If not, revert and try the next hotspot. Do not stack unproven changes.
Keep a short log of the baseline, the change, the new number, and the decision. It stops the team retrying a fix that already failed.
Stop when you reach the target, when the next gain is smaller than the risk, or when the code is about to get much harder to read. Good enough is a real destination. The goal is software that is fast enough for the people using it, not the fastest possible version of every function.
Related reading
These guides cover the skills around this workflow: fixing bugs before tuning, generating useful tests, and reading production signals.
Limits and notes
Profiling tools, hardware, and traffic patterns differ, so the numbers in this guide are examples, not promises. Measure on hardware close to production, with data close to real size, before you commit to a change. If your code handles personal data, keep profiles and logs free of sensitive values, and check your team rules before pasting any production output into an AI tool. When in doubt, reproduce the problem with synthetic data and share that instead.