Hi all,
I happened to need to write a program where it receives data chunks and makes an array of some length. While I tested how much numpy is faster than list slicing.
The test functions is as follows:
import numpy as np
N = 256 # N length array of integer (4-byte)
M = 100 # M chunk num => M * (4N = 1kB) btyes array
## data chunks
tpl = tuple(range(N))
lst = list(range(N))
arr = np.arange(N)
def test_list1():
data = []
for i in range(M):
data += lst
def test_list2():
_lst = [0] * N * M
j = 0
for i in range(M):
_lst[j:j+N] = lst
j += N
def test_array():
_arr = np.zeros(N * M, dtype=int)
j = 0
for i in range(M):
_arr[j:j+N] = arr
j += N
The benchmark:
from timeit import timeit
from matplotlib import pyplot as plt
X = np.arange(100, 2_001, 100)
Y = np.zeros((len(X), 3))
n = 1
k = 40
def _fcalc(j):
global M
data = []
for x in X:
M = int(x)
t1 = timeit(test_list1, number=n) / n
t2 = timeit(test_list2, number=n) / n
t3 = timeit(test_array, number=n) / n
data.append([t1, t2, t3])
print(f"{j}/{k}, {M=:,d}", end='\r')
print()
return data
plt.rcParams["axes.prop_cycle"] = plt.cycler("color", ["blue", "orange", "green",])
yy = []
for j in range(k): # k times trial
y = _fcalc(j)
yy.append(y)
plt.plot(X, y, '.', alpha=0.1)
yy = np.array(yy)
Y = np.median(yy, axis=0)
plt.plot(X, Y, label=["list1", "list2", "array"])
plt.xlabel('M [kiB]')
plt.ylabel('Time [s]')
plt.legend()
plt.grid(1)
plt.show()
Results:
- “list1” (blue line) shows the speed of
test_list1() using list.extend call to create M [kiB] sized array.
- “list2” (orange) is for
test_list2() using list slicing.
- “array” (green) is for
test_array() using ndarray slicing.
The numpy slicing is normally twice as fast as list slicing due to its direct heap access.
Interestingly, less than some size (in this case about 400 kiB), the speed of list.extend call is even faster than the numpy slicing faster than list slicing and almost the same as 'ndarray` slicing. It’s probably caused by L2 cache access, but I’m not a computer expert so I don’t know.
Tested with the CPU:
Intel(R) Core(TM) i3-2350M CPU @ 2.30GHz (core x 2)
L1 cache: 128 KB
L2 cache: 512 KB