Skip to main content

Vectorized operations vs loops

Always prefer vectorized operations over JavaScript loops. numpy-ts operations run on typed arrays with optimized internal loops, avoiding the overhead of JavaScript function calls and dynamic type checks.

Common loop-to-vectorized translations

Loop patternVectorized equivalent
for (i) result[i] = a[i] + b[i]np.add(a, b)
for (i) result[i] = a[i] > threshold ? 1 : 0np.greater(a, threshold)
for (i) sum += a[i]np.sum(a)
for (i) result[i] = Math.max(a[i], 0)np.maximum(a, 0)
for (i) if (mask[i]) result.push(a[i])np.extract(mask, a)
for (i) result[i] = condition ? x[i] : y[i]np.where(condition, x, y)

Avoiding unnecessary copies (use views when possible)

Views share the same underlying data buffer as the original array. Operations that return views are effectively free — no memory allocation and no data copying.

Check whether an operation returned a view

Views share data. Modifying a view changes the original array. If you need an independent copy, use np.copy() or .copy().

Dtype selection for memory efficiency

Choose the smallest dtype that can represent your data. This reduces memory usage and can improve cache performance.

Dtype selection guide

Data typeBytesUse when
float648Maximum precision needed, scientific computation
float324ML inference, graphics, when 7 digits of precision suffice
int324Integer data up to ~2 billion
int162Audio samples, small integer ranges
int8 / uint81Pixel values, boolean-like data, lookup indices
bool1Masks and boolean arrays
Use .astype() to convert between dtypes. Going from a wider type to a narrower one truncates (float to int) or wraps (large int to small int).

Using keepdims for broadcasting

When reducing along an axis, the reduced dimension disappears by default. Use keepdims: true to preserve it as a size-1 dimension, which makes subsequent broadcasting operations work without manual reshaping.