# numba 0.62.1
# llvmlite 0.45.1
# numpy 2.3.4
# OS Windows10
# processor AMD Ryzen 7 PRO 4750GE with Radeon Graphics 3.10 GHz
# RAM 64.0 GB
from typing import NamedTuple
import numpy as np
from numba import njit, prange
from numpy.typing import NDArray
np.random.seed(42)
########### CASE 1 ###################
a = np.empty(10**6, dtype=np.float64)
b = np.empty(10**6, dtype=np.float64)
c = np.empty(10**6, dtype=np.float64)
d = np.empty(10**6, dtype=np.float64)
e = np.empty(10**6, dtype=np.float64)
@njit(parallel=True)
def f1(a, b, c, d, e):
for i in prange(a.shape[0]):
a[i] = a[i] * 100
b[i] = b[i] * 100
c[i] = c[i] * 100
d[i] = d[i] * 100
e[i] = e[i] * 100
return a, b, c, d, e
f1(a, b, c, d, e)
%timeit f1(a, b, c, d, e) # 2.77 ms ± 52 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
########### CASE 2 ###################
A = NamedTuple(
"A",
[
("a", NDArray),
("b", NDArray),
("c", NDArray),
("d", NDArray),
("e", NDArray),
]
)
@njit(parallel=True)
def f1(a):
for i in prange(a.a.shape[0]):
a.a[i] = a.a[i] * 100
a.b[i] = a.b[i] * 100
a.c[i] = a.c[i] * 100
a.d[i] = a.d[i] * 100
a.e[i] = a.e[i] * 100
return a
a = A(
a = np.empty(10**6, dtype=np.float64),
b = np.empty(10**6, dtype=np.float64),
c = np.empty(10**6, dtype=np.float64),
d = np.empty(10**6, dtype=np.float64),
e = np.empty(10**6, dtype=np.float64),
)
f1(a)
%timeit f1(a) # 115 μs ± 1.12 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
I ran the above code to see how much speed difference there is when using NamedTuple for updating multiple array values.
I expected that using NamedTuple would slow things down, but the results were completely different: NamedTuple was overwhelmingly faster.
Is this verification result correct?