0

みんな!オブジェクトでディクショナリの作成パフォーマンスをテストしようとしていますが、奇妙な結果が得られます。Python で大量の辞書を作成する時間を測定するために、3 つの異なる方法を使用しました。最初の解決策は時間モジュールです。私はそれが正確ではないことを知っています。テストファイルは「node_time.py」

from __future__ import print_function
from time import time

class node(object):
    def __init__(self, key, value):
        self.key = key
        self.value = value
        self.right = None
        self.left = None
        self.parent = None
        self.depth = 0
        return

begin = time()
content = [node(i,i) for i in range(1000000)]
print(time()-begin)

2 番目の方法は timeit モジュールです。より良い選択になるはずです。テストファイルは「node_timeit.py」

from __future__ import print_function
from timeit import repeat

class node(object):
    def __init__(self, key, value):
        self.key = key
        self.value = value
        self.right = None
        self.left = None
        self.parent = None
        self.depth = 0
        return

cmd = "content = [node(i,i) for i in range(1000000)]"
prepare = "from __main__ import node"
cost = min(repeat(cmd, prepare, repeat=1, number =1))
print(cost)

3 つ目の方法は、Linux でシステム コマンド「time」を使用する方法です。テストファイルは「node_sys.py」

from __future__ import print_function

class node(object):
    def __init__(self, key, value):
        self.key = key
        self.value = value
        self.right = None
        self.left = None
        self.parent = None
        self.depth = 0
        return

content = [node(i,i) for i in range(1000000)]

最後に、結果はまったく異なります。

-bash-4.2$ python2 node_time.py
5.93654894829
-bash-4.2$ python2 node_timeit.py
2.6723048687
-bash-4.2$ time python2 node_sys.py
real    0m8.587s
user    0m7.344s
sys     0m0.716s

時間モジュール法 (壁時計の時間を測定) の結果は、現在の値よりも大きくなるはずです。しかし、Linux コマンド「time」を使用すると、ユーザー CPU 時間とシステム CPU 時間の合計は 8.060 秒にもなります。正しい結果はどれか。そして、なぜ彼らはそんなに違うのですか?コメントありがとうございます!

4

1 に答える 1

4

timeとのtimeitタイミングの違いは、

デフォルトでは、タイミング中にガベージ コレクションtimeit()を一時的にオフにします。

多くのメモリを割り当てると、通常、循環ガベージ コレクタが作動して、その一部を回収できるかどうかを確認します。より一貫したタイミングを得るためtimeitに、タイミングの間、この動作を無効にします。

timeガベージ コレクションがある場合とない場合のタイミングを比較します。

>>> def t1():
...   s = time.time()
...   content = [node(i, i) for i in range(1000000)]
...   print time.time() - s
...
>>> t1()
3.27300000191
>>> gc.disable()
>>> t1()
1.92200016975

timeitガベージ コレクションの有無にかかわらず、次のようにタイミングを調整します。

>>> gc.enable()
>>> timeit.timeit('content = [node(i, i) for i in range(1000000)]', 'from __main
__ import node; import gc; gc.enable()', number=1)
3.2806941528164373
>>> timeit.timeit('content = [node(i, i) for i in range(1000000)]', 'from __main
__ import node', number=1)
1.8655694847876134

ご覧のとおり、どちらの方法でも同じ GC 設定で同じタイミングが生成されます。

コマンドラインtimeコマンドに関しては、インタープリターのセットアップとティアダウン、および他のタイミングには含まれない他の部分を含む、プログラムのランタイム全体が含まれます。この違いの大きな要因の 1 つは、node割り当てたすべてのオブジェクトを解放するのにかかる時間だと思います。

>>> def t2():
...   s = time.time()
...   [node(i, i) for i in range(1000000)]
...   # List and contents are deallocated
...   print time.time() - s
...
>>> t2()
3.96099996567
于 2014-02-15T05:27:23.583 に答える