[解決済み] なぜPythonではタプルはリストより速いのか?
質問
私は今 "Dive into Python" で、タプルはリストよりも高速であると書かれています。
タプルはイミュータブルで、リストはミュータブルですが、なぜタプルの方が速いのかよくわかりません。
誰かこれの性能テストした人いる?
どのように解決するのですか?
報告されている建設速度比は、以下の場合にのみ成り立ちます。 定数 タプル (項目がリテラルで表現されているもの) のみです。 注意深く観察してください (そしてあなたのマシン上でも繰り返してください -- あなたはシェル/コマンドウィンドウでコマンドを入力するだけでよいのです!)...:
$ python3.1 -mtimeit -s'x,y,z=1,2,3' '[x,y,z]'
1000000 loops, best of 3: 0.379 usec per loop
$ python3.1 -mtimeit '[1,2,3]'
1000000 loops, best of 3: 0.413 usec per loop
$ python3.1 -mtimeit -s'x,y,z=1,2,3' '(x,y,z)'
10000000 loops, best of 3: 0.174 usec per loop
$ python3.1 -mtimeit '(1,2,3)'
10000000 loops, best of 3: 0.0602 usec per loop
$ python2.6 -mtimeit -s'x,y,z=1,2,3' '[x,y,z]'
1000000 loops, best of 3: 0.352 usec per loop
$ python2.6 -mtimeit '[1,2,3]'
1000000 loops, best of 3: 0.358 usec per loop
$ python2.6 -mtimeit -s'x,y,z=1,2,3' '(x,y,z)'
10000000 loops, best of 3: 0.157 usec per loop
$ python2.6 -mtimeit '(1,2,3)'
10000000 loops, best of 3: 0.0527 usec per loop
3.0 での計測を行わなかったのは、もちろん私は 3.0 を持っていないからです。3.1 はあらゆる点で優れているので、完全に時代遅れで、残しておく理由はまったくありません (Python 2.7 にアップグレードできれば、それぞれのタスクで 2.6 よりほぼ 20% 速いと計測できます -- そして 2.6 は、ご覧のように 3.1 より速いです -- ですから、パフォーマンスを真剣に気にするなら Python 2.7 が本当に目指すべき唯一のリリースです !)...。
とにかく、ここでの重要なポイントは、各 Python リリースにおいて、定数リテラルからリストを構築するのは、変数によって参照される値から構築するのとほぼ同じ速度か、わずかに遅いということです。しかしタプルの挙動は非常に異なっています。 どうしてそうなるのか、不思議に思うかもしれませんね。)
答え:定数リテラルから作られたタプルは、Pythonコンパイラによって、それ自体が1つの不変の定数リテラルであると簡単に識別できます。したがって、コンパイラがソースをバイトコードに変換したときに、本質的に一度だけ作られ、関連する関数またはモジュールの「定数テーブル」(quot; constants table)にしまわれるのです。 これらのバイトコードが実行されるとき、事前に構築された定数タプルを回復する必要があるだけです。)
リストは変更可能なオブジェクトであるため、この簡単な最適化はリストには適用できません。
[1, 2, 3]
のような同じ式が二度実行される場合、(ループの中で --
timeit
モジュールはあなたの代わりにループを作ります;-)、新しいリストオブジェクトが毎回新たに構築されます。この構築は(コンパイラがそれをコンパイル時の定数と不変オブジェクトとして些細に識別できない場合のタプルの構築のように)少し時間がかかります。
とはいえ、タプル構築(両方の構築が実際に必要な場合)は、依然として タプル構築はリスト構築の約 2 倍の速さです。 その の違いは、他の回答者が繰り返し述べているように、タプルの単純さによって説明することができます。 しかし、単純な定数リテラルを項目とするリストとタプルの構築のみを比較した場合、その単純さは 6 倍以上のスピードアップを説明するものではありません!_)
関連
-
[解決済み] リストのリストからフラットなリストを作るには?
-
[解決済み] リスト内のアイテムのインデックスを検索する
-
[解決済み] SQLiteのINSERT/per-secondのパフォーマンスを向上させる
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] \0-9]よりも効率が悪い
-
[解決済み] Pythonの「名前付きタプル」とは何ですか?
-
[解決済み] なぜ[]はlist()よりも速いのですか?
-
[解決済み】Pythonに三項条件演算子はありますか?
-
[解決済み] dict を txt ファイルに書き、それを読み取る?
-
[解決済み] Pythonでマルチプロセッシングキューを使うには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] リストとタプル、それぞれを使うべきタイミングは?[重複あり]
-
[解決済み】Pythonではリストよりもタプルの方が効率的ですか?
-
[解決済み] SQLAlchemy: セッションの作成と再利用
-
[解決済み] Pythonのキャッシュライブラリはありますか?
-
[解決済み] Django Rest Framework ファイルアップロード
-
[解決済み] subprocess.run()の出力を抑制またはキャプチャするには?
-
[解決済み] Celeryタスクのユニットテストはどのように行うのですか?
-
[解決済み] Pandasを使って、既存のExcelファイルに新しいシートを保存する方法は?
-
[解決済み] Pythonでランダムなファイル名を生成する最良の方法
-
[解決済み] Pythonの辞書にあるスレッドセーフについて