27

別の質問timeitに答える際に、正の整数と負の整数を使用したリストのインデックス付けの違いをテストするために使用することを提案しました。コードは次のとおりです。

import timeit
t=timeit.timeit('mylist[99]',setup='mylist=list(range(100))',number=10000000)
print (t)
t=timeit.timeit('mylist[-1]',setup='mylist=list(range(100))',number=10000000)
print (t)

私はpython 2.6でこのコードを実行しました:

$ python2.6 test.py
0.587687015533
0.586369991302

次に、python 3.2 で実行しました。

$ python3.2 test.py
0.9212150573730469
1.0225799083709717

それから私は頭をかきむしり、少しグーグル検索をして、これらの観察をここに投稿することに決めました.

オペレーティング システム: OS-X (10.5.8) -- Intel Core2Duo

それは私にとってかなり大きな違いのように思えます (1.5 以上の違い)。特にそのような一般的な操作の場合、python3が非常に遅い理由を知っている人はいますか?

編集

Ubuntu Linux デスクトップ (Intel i7) で同じコードを実行したところ、python2.6 と python 3.2 で同等の結果が得られました。これは、オペレーティング システム (またはプロセッサ) に依存する問題のようです (他のユーザーは、Linux マシンで同じ動作を見ています -- コメントを参照してください)。

編集2

回答の 1 つでスタートアップ バナーが要求されたので、次のようになります。

Python 2.6.4 (r264:75821M, Oct 27 2009, 19:48:32) 
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin

と:

Python 3.2 (r32:88452, Feb 20 2011, 10:19:59) 
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin

アップデート

http://www.python.org/download/から python2.7.3 と python3.2.3 の新しいバージョンをインストールしました

どちらの場合も、私は

「Python xx3 Mac OS X 32 ビット i386/PPC インストーラー (Mac OS X 10.3 から 10.6 用 [2])」

私はOS X 10.5を使用しているため。新しいタイミングは次のとおりです (複数の試行を通じて合理的に一貫しています)。

パイソン2.7

$python2.7 test.py
0.577006101608
0.590042829514

パイソン3.2.3

$python3.2 test.py
0.8882801532745361
1.034242868423462
4

3 に答える 3

24

これは、Python 3.2 の一部のビルドのアーティファクトのようです。現時点での最良の仮説は、すべての 32 ビット Intel ビルドで速度が低下するが、64 ビット ビルドでは速度が低下しないというものです。詳細については、以下をお読みください。

何かを判断するのに十分なテストをほとんど実行していません。テストを何度も繰り返したところ、同じテストで 0.31 から 0.54 の範囲の値が得られました。これは大きな変動です。

だから、私はあなたのテストを10x番号 とrepeat=10で実行し、さまざまな Python2 と Python3 のインストールを使用しました。上位と下位の結果を破棄し、残りの 8 を平均し、10 で割ります (テストに相当する数値を取得するため)。

 1. 0.52/0.53 Lion 2.6
 2. 0.49/0.50 Lion 2.7
 3. 0.48/0.48 MacPorts 2.7
 4. 0.39/0.49 MacPorts 3.2
 5. 0.39/0.48 HomeBrew 3.2

[99]つまり、3.2 は実際には の方がわずかに速く、 とほぼ同じ速度のように見えます[-1]

ただし、10.5 マシンでは、次の結果が得られました。

 1. 0.98/1.02 MacPorts 2.6
 2. 1.47/1.59 MacPorts 3.2

元の (Lion) マシンに戻って、32 ビット モードで実行したところ、次の結果が得られました。

 1. 0.50/0.48 Homebrew 2.7
 2. 0.75/0.82 Homebrew 3.2

したがって、重要なのは 32 ビットであるように思われ、Leopard と Lion、gcc 4.0 と gcc 4.2、clang、ハードウェアの違いなどではありません。異なるコンパイラなどを使用して、Leopard で 64 ビット ビルドをテストすると役立つでしょう。残念ながら、私の Leopard ボックスは第 1 世代の Intel Mini (32 ビット Core Solo CPU を搭載) であるため、そのテストを行うことはできません。

さらなる状況証拠として、Lion ボックスで他の多くの簡単なテストを実行したところ、32 ビット 3.2 は 2.x よりも 50% 遅く、64 ビット 3.2 はおそらく 2 より少し速いようです。バツ。しかし、本当にそれをバックアップしたい場合は、誰かが実際のベンチマーク スイートを選択して実行する必要があります。

とにかく、現時点での私の推測では、3.x ブランチを最適化するとき、誰も 32 ビット i386 Mac ビルドに多大な労力を費やしていなかったということです。これは、実際に彼らが行った合理的な選択です。

あるいは、彼らは 32 ビット i386 の期間にあまり力を入れていませんでした。その可能性は、OPがLinuxボックスで2.xと3.2が同様の結果をもたらすのを見た理由を説明するかもしれませんが、Otto AllmendingerはLinuxボックスで3.2が2.6と同様に遅いと見ました. しかし、どちらも 32 ビットまたは 64 ビットのどちらの Linux を実行しているかについて言及していないため、それが関連しているかどうかを判断するのは困難です。

除外していない可能性は他にもたくさんありますが、これが最善の方法のようです。

于 2012-07-09T18:24:18.240 に答える
4

これが答えの少なくとも一部を説明するコードです:

$ python
Python 2.7.3 (default, Apr 20 2012, 22:44:07) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import timeit
>>> t=timeit.timeit('mylist[99]',setup='mylist=list(range(100))',number=50000000)
>>> print (t)
2.55517697334
>>> t=timeit.timeit('mylist[99L]',setup='mylist=list(range(100))',number=50000000)
>>> print (t)
3.89904499054

$ python3
Python 3.2.3 (default, May  3 2012, 15:54:42) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import timeit
>>> t=timeit.timeit('mylist[99]',setup='mylist=list(range(100))',number=50000000)
>>> print (t)
3.9906489849090576

python3には古いint型がありません。

于 2012-07-09T20:14:38.090 に答える
0

Python 3range()は Python 2xrange()です。range()Python 3 コードでPython 2 をシミュレートする場合は、 list(range(num). が大きいほど、num元のコードとの違いが大きくなります。

リストにはターゲット オブジェクトへの参照のみが格納されるため、インデックス作成はリスト内に格納されているものに依存しない必要があります。参照は型指定されておらず、すべて同じ種類です。したがって、リスト型は同種のデータ構造です (技術的には)。インデックス化とは、インデックス値を開始アドレス + オフセットに変換することを意味します。オフセットの計算は非常に効率的で、減算は最大 1 回です。これは、他の操作に比べて非常に安価な追加操作です。

于 2012-07-09T22:24:11.557 に答える