inを使うと遅くなります。

numpy.array(bool)の対角成分にTrueが存在するかどうかを判定するスクリプトの速度比較をしているときに気づきました。

  • True in a.diagonal()
  • np.sum(a.diagonal()) > 0

のどちらが速いのか、という検証です。以下のコードで検証しました。

import numpy as np
from datetime import datetime
for n in [10,100,1000,10000,100000]:
    print("n = {} ----------------------------".format(n))
    a = np.random.randint(2, size=(n,n), dtype=bool)
    # case 1
    start = datetime.now()
    print("start 1")
    print(True in a.diagonal())
    print(str(datetime.now() - start))
    # case 2
    start = datetime.now()
    print("start 2")
    print(np.sum(a.diagonal()) > 0)
    print(str(datetime.now() - start))

1回目の実行結果

n = 10 ----------------------------
start 1
False
0:00:00.004052
start 2
True
0:00:00.000997
n = 100 ----------------------------
start 1
False
0:00:00.000965
start 2
True
0:00:00.000995
n = 1000 ----------------------------
start 1
False
0:00:00.000998
start 2
True
0:00:00.008972
n = 10000 ----------------------------
start 1
False
0:00:00.000965
start 2
True
0:00:00.000954
n = 100000 ----------------------------
start 1
False
0:00:09.391776
start 2
True
0:00:00.012965

2回目

n = 10 ----------------------------
start 1
False
0:00:00.000995
start 2
True
0:00:00.000999
n = 100 ----------------------------
start 1
False
0:00:00.001000
start 2
True
0:00:00.001996
n = 1000 ----------------------------
start 1
False
0:00:00.001008
start 2
True
0:00:00
n = 10000 ----------------------------
start 1
False
0:00:00.001995
start 2
True
0:00:00.001006
n = 100000 ----------------------------
start 1
False
0:00:00.054854
start 2
True
0:00:00.008979

3回目

n = 10 ----------------------------
start 1
False
0:00:00.001001
start 2
True
0:00:00.003984
n = 100 ----------------------------
start 1
False
0:00:00.001010
start 2
True
0:00:00.001991
n = 1000 ----------------------------
start 1
False
0:00:00.011963
start 2
True
0:00:00.001004
n = 10000 ----------------------------
start 1
False
0:00:00.002002
start 2
True
0:00:00.000984
n = 100000 ----------------------------
start 1
False
0:00:02.256627
start 2
True
0:00:00.011967

正方行列の1辺の次元が100だとTrue in *の方が速いのですが、1000以上だともう圧倒的にnp.sum(*) > 0が速くなります。

これはnumpyのソースコードを見ないと分からないですが、”True in*”だと要素ごとに比較演算をするのに対して”np.sum(*) > 0″だと一気に加算できるので速いのでしょうね。”True in*”だとTrueを発見した時点でbreakできるのでもしかすると速いのかも、と思っていましたが加算の最適化のほうが圧倒的だということでしょう。

この結果から、

  • True in * → np.sum(*) > 0
  • False in * → np.sum(*) < len(*)
  • True not in * → np.sum(*) == 0
  • False not in * → np.sum(*) == len(*)

※*はnumpy.array(bool)

とすると(特に大きな次元のデータは)高速に処理できることがわかります。

関連記事

fitbitの睡眠スコアを90弱で安定させる良い睡眠を続ける簡単な方法

m1 ipad pro 12.9 2021のusb-cハブはコレがベスト

Time Machine不要!Macを11.2.3にダウングレードして原神をm1 macbook airでプレイする

MH-Z19CとM5StickCで二酸化炭素濃度モニタリング

【神軽量HMD】Avegant Glyph 改造: 瓶詰堂さんのaltglyphを作った

PC、iPad、Android、switchもドックいらず!あまりに万能なusb-cハブが最強だった

コメント

コメントを返信する

メールアドレスが公開されることはありません。 が付いている欄は必須項目です