4

私はいくつかの非常に簡単なテストを書きました(私は知っています、それらは「決定的」ではありませんが、それらは私を興味深くさせます)。私は最適化とそのすべてのジャズで走りました。

from time import time

alist = [ 2, 4, 6, 8, 10, 12, 24, 48, 64, 128 ]

def all_even( alist ):
    for val in alist:
        if not (val & 1) == 0:
            return False
    return True

def all_even_bad( alist ):
    result = False
    for val in alist:
        if not (val & 1) == 0:
            result = False
        else:
            result = True
    return result

def main():
    start = time()
    for i in range(1, 10000):
        all_even( alist )
    print('All even: {0}'.format(time() - start))

    start = time()
    for i in range(1, 10000):
        all_even_bad( alist )
    print('All even bad: {0}'.format(time() - start))


    start = time()
    for i in range(1, 10000):
        all( val & 1 == 0 for val in alist )
    print('All one: {0}'.format(time() - start))


if __name__ == '__main__':
    main()

私は周りに結果を得る:

> All even: 2.86299991608 
> All even bad: 3.71399998665 
> All one: 3.89900016785

組み込み関数は早期に解決しないようですか?

4

3 に答える 3

7

all()間違いなく早期に終了します。動作の違いは、ジェネレーターの作成に必要なオーバーヘッドの結果にすぎないと思います。

all()これが早期に終了するいくつかの証拠です:

In [8]: alist = [3] + [0] * 2**20    # alist bigger, with an early odd

In [10]: %timeit all_even(alist)
1000000 loops, best of 3: 309 ns per loop

In [11]: %timeit all_even_bad(alist)
10 loops, best of 3: 133 ms per loop

In [12]: %timeit all(val & 1 == 0 for val in alist)
1000000 loops, best of 3: 891 ns per loop

all()ここよりも低速ですがall_even()、早期に終了しないバージョンの関数よりも大幅に高速であることに注意してください。

于 2012-07-20T17:11:25.337 に答える
3

テストに失敗する要素はないため、テストを短絡させる方法はありません。

于 2012-07-20T17:11:36.003 に答える
1

あなたのリストのすべての数字は実際には偶数であるため、論理的に早期に救済することはできませんでしたか?呼び出しのオーバーヘッドはall()、オブジェクトの構築に起因する場合がありgeneratorます。

于 2012-07-20T17:11:26.473 に答える