A loop over a million rows is fine in a tutorial and slow in production. The fix is not cleverer code, it is moving the inner step into a library that does it in C. Measure before you optimise, and measure after.
What you will see
The same number, faster - the loop moved into C. Same answer is the point, not the timing.
About 2 min of reading
Quick check
Before this new lesson, one small question about the lesson you just finished. Recall it, do not look it up.
Try It
Compare a loop to a comprehension on the same work.
1
Time the loop version
import time
t = time.time()
acc = 0
for i in range(1_000_000):
acc += i
print(acc, round(time.time() - t, 3))
Before you run it, say out loud what it will print. Then open the answer.
What it prints
499999500000 and a time around a tenth of a second or more.
2
Time the built-in version
t = time.time()
print(sum(range(1_000_000)), round(time.time() - t, 3))
Before you run it, say out loud what it will print. Then open the answer.
What it prints
The same number, faster - the loop moved into C. Same answer is the point, not the timing.
Put it in order
Before you write anything, put these lines back in the right order. Click a line to move it up one step. This support step is easier than writing code from scratch, and it is here to make the last example stick.
Data Flow
Work moves from per element to per batch.
1Time the whole script
↓
2Find the step that dominates
↓
3Move that step into a library call
↓
4Assert the answer is unchanged
Line by line
Read the first example one line at a time. A line that prints shows what appears on screen; the rest set things up quietly.
import timesets nothing on screen
t = time.time()sets nothing on screen
acc = 0sets nothing on screen
for i in range(1_000_000):sets nothing on screen
acc += isets nothing on screen
print(acc, round(time.time() - t, 3))499999500000 and a time around a tenth of a second or more.
Why this worksCorrectness first, then speed
A vectorised version that gives a different answer is worse than a slow version that is right. Keep the readable loop as a test case and assert the fast version matches it on a small input.
Memory is a limit too
Loading a file that is larger than RAM fails, and the failure is a crash rather than a slow answer. Stream in chunks or aggregate in one pass when the dataset will not fit, and know the size before you try.
Examples
Time it before you change it
Wrap the step in a timer and print seconds. If the whole script takes 0.4 seconds, an optimisation is noise. If one step takes 40 of the 45 seconds, that is the only thing worth changing.
Vectorise the inner step
In Python, a list comprehension or a numpy operation replaces a per element loop; in JavaScript, one typed array operation replaces a per element loop. The win is that the per element work leaves the interpreter.
Read once, reuse many times
The biggest speedups come from not repeating work: parse the file once, cache the index, and reuse the parsed rows across all the questions. Re-reading a file inside a loop is the bug that turns seconds into minutes.
Words this lesson uses
Each one is defined here on this site. Open the entry for the full definition and the other words it points at.