0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【97ケース実測】NumPyはどれだけ速いのか?Pythonリストと徹底比較した結果、最大4430倍早かった

0
Last updated at Posted at 2026-03-01

はじめに

「NumPyは速い」と言われますが、処理内容とデータサイズで差は大きく変わります。
この記事では、Python標準のリスト実装とNumPy実装を同じ処理で比較し、97ケースを計測しました。

先に全体傾向です。

  • NumPyが遅かったのは97件中2件(どちらも小規模データ)
  • 速度倍率(Python/NumPy)の中央値は 22.9倍
  • 大規模データでは100倍超が何度も出る

検証コードのレポジトリ (likeお願いします)

実際のコードと比較結果(平均倍率が高い順)

各項目は「同じ入力データ」を Python(list)NumPy(ndarray) で比較しています。

1) 行列積(Matrix multiplication / GEMM)

Python(list)

py_list_result = [[sum(A_list[i][k] * B_list[k][j] for k in range(n)) for j in range(n)] for i in range(n)]

NumPy(ndarray)

np_arr_result = A_arr @ B_arr

速度:

  • N=100: 4430.5x

2) 線形代数(Linear algebra)

Python(list)

py_list_result = [sum(x * y for x, y in zip(row, vec_list)) for row in mat_list]

NumPy(ndarray)

np_arr_result = mat_arr @ vec_arr

速度:

  • N=100: 292.8x
  • N=500: 477.3x
  • N=1,000: 422.6x

3) インデックス参照・スライシング・結合(Indexing, slicing, concatenation)

Python(list)

for i in range(n): py_list_work[i] += 1.0

NumPy(ndarray)

np_arr_work += 1.0

速度:

  • N=100: 7.8x
  • N=10,000: 327.6x
  • N=1,000,000: 289.6x

4) 前処理・正規化(Preprocessing / Normalization)

Python(list)

py_list_result = [sum(data_list[i:i+5]) / 5 for i in range(len(data_list) - 4)]

NumPy(ndarray)

np_arr_result = np.convolve(data_arr, np.ones(5) / 5, mode="valid")

速度:

  • N=100: 17.4x
  • N=10,000: 226.0x
  • N=1,000,000: 277.2x

5) 集約・還元(Aggregation / Reduction)

Python(list)

py_list_result = [sum(row[c] for row in mat_list) for c in range(n)]

NumPy(ndarray)

np_arr_result = np.sum(mat_arr, axis=0)

速度:

  • N=100: 80.2x
  • N=500: 173.7x
  • N=1,000: 248.8x

6) 要素単位演算(Element-wise operations)

Python(list)

py_list_result = [x + 1.5 for x in data_list]

NumPy(ndarray)

np_arr_result = data_arr + 1.5

速度:

  • N=100: 5.8x
  • N=10,000: 112.7x
  • N=1,000,000: 181.1x

7) 条件選択・ブールマスキング(Conditional selection / Boolean masking)

Python(list)

py_list_result = [-1.0 if x < -0.5 else (1.0 if x > 0.5 else 0.0) for x in data_list]

NumPy(ndarray)

np_arr_result = np.where(data_arr < -0.5, -1.0, np.where(data_arr > 0.5, 1.0, 0.0))

速度:

  • N=100: 1.9x
  • N=10,000: 22.9x
  • N=1,000,000: 26.1x

8) 数学関数(Mathematical functions)

Python(list)

py_list_result = [math.log1p(abs(x)) for x in data_list]

NumPy(ndarray)

np_arr_result = np.log1p(np.abs(data_arr))

速度:

  • N=100: 6.5x
  • N=10,000: 9.4x
  • N=1,000,000: 8.9x

9) ソート・順位付け(Sorting / Ranking)

Python(list)

py_list_result = sorted(data_list, reverse=True)[:10]

NumPy(ndarray)

np_arr_result = np.sort(data_arr)[-10:][::-1]

速度:

  • N=100: 1.4x
  • N=10,000: 3.8x
  • N=200,000: 4.0x

全33種類の処理の実装式と平均倍率(高い順)

カテゴリ(Category) 処理名(Operation) Python実装 NumPy実装 平均倍率
行列積(Matrix multiplication / GEMM) matmul [[sum(A[i][k]*B[k][j] for k in range(n)) for j in range(n)] for i in range(n)] A @ B 4430.5x
インデックス参照・スライシング・結合(Indexing, slicing, concatenation) slice_strided d[::2] d[::2] 3204.5x
インデックス参照・スライシング・結合(Indexing, slicing, concatenation) slice_contiguous d[start:end] d[start:end] 1710.1x
線形代数(Linear algebra) matvec [sum(x * y for x, y in zip(row, v)) for row in m] m @ v 397.5x
インデックス参照・スライシング・結合(Indexing, slicing, concatenation) in_place_add for i in range(n): work[i] += 1.0 work[:] += 1.0 208.3x
前処理・正規化(Preprocessing / Normalization) rolling_mean_w5 [sum(d[i:i+5]) / 5 for i in range(len(d)-4)] np.convolve(d, np.ones(5)/5, mode="valid") 173.5x
集約・還元(Aggregation / Reduction) sum_axis_0 [sum(row[c] for row in m) for c in range(n)] np.sum(m, axis=0) 167.6x
線形代数(Linear algebra) broadcast_add [[x + y for x, y in zip(row, v)] for row in m] m + v 101.8x
要素単位演算(Element-wise operations) scalar_add [x + 1.5 for x in d] d + 1.5 99.9x
線形代数(Linear algebra) dot_1d sum(x * y for x, y in zip(a, b)) np.dot(a, b) 99.3x
インデックス参照・スライシング・結合(Indexing, slicing, concatenation) copy_add new_d = [x + 1.0 for x in d] new_d = d + 1.0 94.7x
要素単位演算(Element-wise operations) scalar_mul [x * 1.5 for x in d] d * 1.5 90.2x
集約・還元(Aggregation / Reduction) max_axis_1 [max(row) for row in m] np.max(m, axis=1) 64.4x
要素単位演算(Element-wise operations) affine_transform [(x * 1.1) + 0.3 for x in d] (d * 1.1) + 0.3 61.5x
数学関数(Mathematical functions) sqrt_abs [math.sqrt(abs(x) + 1e-12) for x in d] np.sqrt(np.abs(d) + 1e-12) 59.3x
前処理・正規化(Preprocessing / Normalization) minmax_scale [(x - min_v) / (max_v - min_v) for x in d] (d - min_v) / (max_v - min_v) 50.6x
集約・還元(Aggregation / Reduction) std_1d math.sqrt(sum((x-mean)**2 for x in d)/len(d)) np.std(d) 48.2x
前処理・正規化(Preprocessing / Normalization) zscore [(x - mean) / std for x in d] (d - mean) / std 43.4x
前処理・正規化(Preprocessing / Normalization) zscore_clip [max(-2.0, min(2.0, (x - mean) / std)) for x in d] np.clip((d - mean) / std, -2, 2) 38.0x
要素単位演算(Element-wise operations) clip [1 if x > 1 else (-1 if x < -1 else x) for x in d] np.clip(d, -1, 1) 35.6x
条件選択・ブールマスキング(Conditional selection / Boolean masking) binary_threshold [1.0 if x > 0 else 0.0 for x in d] np.where(d > 0, 1.0, 0.0) 30.8x
条件選択・ブールマスキング(Conditional selection / Boolean masking) relu_fill [x if x > 0 else 0.0 for x in d] np.where(d > 0, d, 0.0) 23.1x
条件選択・ブールマスキング(Conditional selection / Boolean masking) ternary_bucket [-1.0 if x < -0.5 else (1.0 if x > 0.5 else 0.0) for x in d] np.where(d < -0.5, -1.0, np.where(d > 0.5, 1.0, 0.0)) 17.0x
集約・還元(Aggregation / Reduction) sum_axis_1 [sum(row) for row in m] np.sum(m, axis=1) 12.9x
集約・還元(Aggregation / Reduction) mean_axis_1 [sum(row) / len(row) for row in m] np.mean(m, axis=1) 12.1x
数学関数(Mathematical functions) sin [math.sin(x) for x in d] np.sin(d) 9.8x
集約・還元(Aggregation / Reduction) quantile_90 sorted_d[round(0.9 * (len(d) - 1))] np.quantile(d, 0.9, method="nearest") 9.0x
数学関数(Mathematical functions) log1p_abs [math.log1p(abs(x)) for x in d] np.log1p(np.abs(d)) 8.3x
数学関数(Mathematical functions) exp [math.exp(x) for x in d] np.exp(d) 8.1x
インデックス参照・スライシング・結合(Indexing, slicing, concatenation) concat left + right np.concatenate((left, right)) 5.7x
条件選択・ブールマスキング(Conditional selection / Boolean masking) filter_gt_0_5 [x for x in d if x > 0.5] d[d > 0.5] 5.0x
ソート・順位付け(Sorting / Ranking) top10_desc sorted(d, reverse=True)[:10] np.sort(d)[-10:][::-1] 3.1x
ソート・順位付け(Sorting / Ranking) sort_asc sorted(d) np.sort(d) 3.1x

結果(全体)

results_comprehensive.csv(97行)から集計しました。

  • NumPyが遅いケース: 2/97
  • 速度倍率の中央値: 22.9x
  • 四分位範囲: 6.5x 〜 97.9x
  • 最小: 0.2xquantile_90, N=100
  • 最大: 9505.6xslice_strided, N=1,000,000

カテゴリ平均(抜粋):

  • ソート・順位付け(Sorting / Ranking): 3.1x
  • 数学関数(Mathematical functions): 21.4x
  • 前処理・正規化(Preprocessing / Normalization): 76.4x
  • 線形代数(Linear algebra): 199.6x
  • 行列積(Matrix multiplication / GEMM): 4430.5x

代表ケースの速度(高い順)

  1. matmul (N=100): 4430.5x
  2. in_place_add vs copy_add (N=1,000,000): 289.6x vs 180.2x
  3. rolling_mean_w5 (N=1,000,000): 277.2x
  4. sum_axis_0 vs sum_axis_1 (N=1000): 248.8x vs 15.0x
  5. scalar_add (N=1,000,000): 181.1x
  6. top10_desc (N=200,000): 4.0x

NumPyが遅かったケース

  1. quantile_90, N=100: 0.2x
  2. concat, N=100: 0.4x

いずれも小規模データで、NumPy呼び出しの固定コストが効いたケースです。

再現手順

./.venv/bin/python benchmark_business_comprehensive.py

生成物:

  • results_comprehensive.csv
  • summary_comprehensive.md

まとめ

今回の97ケース比較では、NumPyは多くの場面で高速でした。
ただし小規模データでは逆転も起きるため、実装の選択は処理内容とデータサイズで決めるのが確実です。

検証コードのレポジトリ (likeお願いします)

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?