Find the work repeated inside the loop
This authored Python example returns the total after each integer value arrives:
def running_totals_slow(values):
return [sum(values[:i + 1]) for i in range(len(values))]
For [3,-2,5], the answer is [3,1,6]. The function sums one value, then two, then three, for six additions under the simple counting model. Each slice also creates another list. For n inputs, adding the prefix lengths gives n(n+1)/2; that grows quadratically.
Python's built-in function reference documents sum. The repeated scan comes from how this function calls it, not from sum being an inherently poor choice.
Keep the useful total as you go
def running_totals(values):
result = []
total = 0
for value in values:
total += value
result.append(total)
return result
The contract here accepts a list of Python integers, preserves its order and contents, and returns a new list. Empty input returns []. Negative values are valid. Arbitrary objects, side-effectful addition methods and floating-point reproducibility are outside this example's contract; do not extend the claim to them without new checks.
Both versions still need an output list proportional to the input size. A generator could change memory behavior but would also change the return interface. That requires a separate caller decision.
Check equivalence before timing
| Input | Expected result |
|---|---|
| [] | [] |
| [0] | [0] |
| [3,-2,5] | [3,1,6] |
| [-4,-1] | [-4,-5] |
Run both functions on these cases. Assert the input is unchanged and the returned list is a separate object. Then use representative larger integer data to compare their complete results. A single matching final total would miss incorrect intermediate values.
Ask for an explanation you can test
Analyze this Python function for repeated work.
Code and supported Python version: [PASTE]
Contract and callers: [PASTE]
Representative sizes and value types: [PASTE]
Measured slow part and timing method: [PASTE OR NOT YET MEASURED]
Explain the current operation growth and allocation behavior.
Propose one candidate preserving output values, order, type and input
state. State the input domain your equivalence argument needs.
Give explicit correctness fixtures and a fair timing comparison.
Separate derived operation counts from measured elapsed time.
Do not invent speedups or optimize unrelated code.
OpenAI's prompting documentation supports supplying relevant context and the intended result. The measurements and contract give the optimization proposal something concrete to answer.
Time the same operation under comparable conditions
Create the input before starting the timer. Time the function call and result creation for both versions with the same data and runtime. Exclude printing, importing and input generation unless those are deliberately part of the workload. Use several input sizes and repeated measurements; note the Python version, sizes and calls per timing sample.
The timeit documentation, checked October 24, 2026, explains setup and repeated timings. It also discusses interference and how to interpret the repeated results. If you report a ratio, include enough of that setup for someone else to reproduce it. No elapsed-time result is asserted for this teaching example.
An operation-count improvement may be compelling for large inputs yet irrelevant to a tiny report that already finishes within its budget. Check the surrounding application too: file reading or rendering might dominate after this function becomes cheaper.
For database execution, use the separate SQL optimization workflow, whose evidence includes query plans and database conditions. For this local function, keep the before/after code, equality checks and measured baseline together, then decide whether the observed improvement justifies the change.