0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

速いビットカウントは bin().count('1')

Posted at

BitBoard を利用してリバーシを実装しています。
石の数は 立っている bit の数を数える(ビットカウントする)ことで求められます。

いくつか実装を比べてみましたが、お手軽な実装が速いです。

bin_count
def count1(board):
    return bin(board).count('1')

当初、文字列を経由するので遅いのではないかと思いましたが、最適化されていて速いんだと思います。
試してみたコードは以下です。

# 呼び出しのオーバーヘッド計測のためのダミー関数
def dummy(board):
    return 0

# popcount の実装
def count2(board):
    board = (board & 0x5555555555555555) + (board >> 1 & 0x5555555555555555)
    board = (board & 0x3333333333333333) + (board >> 2 & 0x3333333333333333)
    board = (board & 0x0f0f0f0f0f0f0f0f) + (board >> 4 & 0x0f0f0f0f0f0f0f0f)
    board = (board & 0x00ff00ff00ff00ff) + (board >> 8 & 0x00ff00ff00ff00ff)
    board = (board & 0x0000ffff0000ffff) + (board >> 16 & 0x0000ffff0000ffff)
    return (board & 0x00000000ffffffff) + (board >> 32)

# 愚直な方法
def count3(board):
    result = 0
    while board:
        board >>= 1
        result += board & 1
    return result

def main():
    board = 0b0010000000100000000011000011010000111100000110000000000000000000

    import time

    temp = time.time()
    for i in range(100000):
        dummy(board)
    print(f"dummy : {time.time() - temp}")

    temp = time.time()
    for i in range(100000):
        count1(board)
    print(f"count1: {time.time() - temp}")

    temp = time.time()
    for i in range(100000):
        count2(board)
    print(f"count2: {time.time() - temp}")

    temp = time.time()
    for i in range(100000):
        count3(board)
    print(f"count3: {time.time() - temp}")

if __name__ == "__main__":
    main()

結果は以下です。

dummy : 0.010009050369262695
count1: 0.0470428466796875
count2: 0.152146577835083
count3: 1.0559582710266113

count1 は 呼び出し(dummy)のオーバーヘッドと同じオーダーで計算できています。
count2 のアルゴリズムは popcount と呼ばれる O(logN) のアルゴリズムを利用していますが、遅いです。
count3 と比べると差は歴然です。

0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?