5.4.5 · D1Scientific Computing (Python)

Foundations — Vectorization — avoiding Python loops, speed comparison

1,811 words8 min readBack to topic

Before you can feel why vectorization wins, you must be able to read every symbol the parent note throws at you. This page builds each one from nothing — plain words first, then a picture, then why the topic needs it.


0. What is a "number in memory" anyway?

Everything below rests on one fact: how a value is stored decides how fast you can use it.

The picture: think of memory as a long ruler marked off in tiny cells. A float64 occupies 8 consecutive cells and nothing extra.

Figure — Vectorization — avoiding Python loops, speed comparison

Why the topic needs it: the whole speed story is "packed raw numbers vs. scattered boxed objects." You cannot understand the difference until you can see what "packed raw" looks like on the ruler. See NumPy Arrays vs Python Lists for the full comparison.


1. A boxed object vs. a raw value

The picture: a raw float64 is a bare number on the ruler. A boxed number is that value hidden inside a cardboard box, and the box sits somewhere else in memory with a string tied from your list to the box.

Figure — Vectorization — avoiding Python loops, speed comparison

Why the topic needs it: the parent note lists the loop's four costs — fetch object, check type, dispatch method, allocate new object. Every one of those exists only because the number is boxed. Remove the box (use a NumPy array) and all four costs vanish.


2. — the count of elements

The picture: is the length of the row on the ruler.

Why the topic needs it: the cost of a loop is "cost-per-item × number-of-items." That multiplication is where slowness compounds. is the multiplier.

Reveal check
= one million; = ten million.

3. Time and its units — ns, ms, s

The picture: a bar chart of shrinking blocks, each 1000× thinner than the last.

Why the topic needs it: the parent quotes " ns" and " ns." Those numbers are meaningless unless you know a nanosecond is a billionth of a second, so a million of them is only s = 1 ms.

Reveal check — how many nanoseconds in one second?
(one billion).

4. (tau) and — cost per element and fixed setup

The picture: imagine two receipts. One (setup) is a flat entry fee. The other grows one line per item.

Why the topic needs it: the entire time model is just "flat fee plus per-item fee times number of items." Every symbol you now know:

Symbol Plain words Picture
total time height of the whole receipt
fixed startup time the flat entry line
how many elements number of item-lines
time for one element cost of one item-line
Figure — Vectorization — avoiding Python loops, speed comparison

5. The ratio, the limit, and the arrow

Why the topic needs it: the headline "" is a limit. As , the fixed becomes a rounding error, so The 's cancel because both top and bottom grow in step; only the per-element ratio survives.


6. Big-O — one word for "how cost scales"

The picture: a straight line () versus an upward-curving parabola ().

Why the topic needs it: the parent's biggest trapnp.append inside a loop — is bad precisely because it turns an job into : each append copies the whole array, so total copying is . You need Big-O to see why that's catastrophic. Full detail in Big-O Complexity.


7. Vocabulary that rides along

Why the topic needs it: these are the verbs of vectorization. Every "FAST" code block in the parent is one of them: arithmetic → ufunc, + across shapes → broadcasting, a[a<0]=0 → mask.


The prerequisite map

bits and float64 in memory

boxed PyObject vs raw value

N the element count

four loop costs per element

time model T equals setup plus N times tau

time units ns ms s

speedup ratio and the limit

Vectorization speed model

Big-O growth shapes

why np append is bad

ufuncs masks broadcasting

Read it top-down: memory layout and counting feed the cost model; the cost model plus units give the speedup limit; Big-O explains the mistakes; the named tools are how you actually do it.


Equipment checklist

Tick each only when you can answer without peeking.

What is a float64 and how many bytes does it use?
A real number packed into a fixed 64-bit pattern; 8 bytes.
What does "boxing" a number mean?
Wrapping the raw value inside a PyObject that also stores its type and reference count.
Which four costs does a Python loop pay per element?
Fetch object, runtime type-check, method dispatch, allocate a new result object.
What does stand for?
The number of elements in the array.
How many nanoseconds are in one second?
(one billion).
In , what is each symbol?
total time, one-time startup, element count, time per element.
Why does the speedup approach as ?
The -terms dominate over the fixed , so the constant becomes negligible and the 's cancel.
What does mean in words?
Work grows with the square of the input — double the data means four times the time.
What is a boolean mask?
An array of True/False values used to select elements without a Python if.
What is a ufunc?
A pre-compiled C kernel (like np.add) that runs the element loop outside Python.