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)

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

関連記事

echo spotでスマホを持ってない人とテレビ電話をする方法

MiSTEL BAROCCO MD650Lをbluetooth接続にしてmobilityを爆上げ

MiSTEL BAROCCO MD650Lを持ち運びやすくするマグネット足を作った

MiSTEL BAROCCO MD650Lレビュー: 左右分離型ロープロのメカニカルキーボード

workaround for a Orange PI problem USB WiFi with Armbian cannot be found from network

中華系防水bluetoothイヤホンでちゃんと防水できたのは1社だけだった

コメント

コメントを返信する

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