2013-08-29 8 views
5

が、著者はPythonで異なる文字列連結方法の効率を比較する文字列の連結のための文字配列よりも速くリストされています3(文字列のリストを結合する)は、方法4(文字列のリストを結合する)よりも著しく遅い結果となる。はなぜ以下のリンク先の記事で

両方とも可変であり、私はそれらが同等の性能を持つべきだと思うだろう。

+0

おそらく、 '配列。文字列'は 'str.join'にあるように最適化されていません。 – abarnert

+3

また、この記事は2004年のものです。Naive strの追加はPythonの新しいバージョンでははるかに高速で、 'str.join'もそうです... – abarnert

+0

@abarnertとは全く関係があります。この記事が書かれたとき、最新のPythonバージョンは2.3.3でした(http://www.python.org/download/releases/とhttp://www.python.org/download/releases/2.3.4/を参照)。 )。その時点で行われたベンチマークは今日ほとんど意味がありません。 –

答えて

4

「どちらも変更可能です」というのはあなたを少し誤解しています。

リストアペンドメソッドでリストが変更可能であることは事実です。しかし、リストを構築することは遅い部分ではありません。平均長が1000の文字列が1000個ある場合は、配列に対して1000000個の突然変異を行いますが、1000個の突然変異のみをリストに加えます(文字列オブジェクトに対して1000個のインクリメントを加えます)。

特に、これは、arrayが1000倍の時間を費やさなければならないことを意味します(新しいストレージの割り当てとこれまでの全体のコピー)。

リストメソッドの遅い部分は、最後にstr.joinコールです。しかし、ではありません。拡張が必要ではありません。 2つのパスを使用して、最初に必要なサイズを計算し、次にすべてをそのパスにコピーします。

str.joinのコードは、多くの実際のプログラムが依存する非常に一般的で推奨されるイディオムであるため、それを最適化するための多くの作業を行っていました。毎日。 arrayは、最初に言語に追加されて以来、ほとんど触れられていません。

しかし、実際に違いを理解したい場合は、ソースを確認する必要があります。 2.7では、配列メソッドの主な作業はarray_fromstringであり、リストメソッドの主な作業はstring_joinです。後者は、開始時に結合しようとしている文字列のすべてを既に知っているという事実を利用する方法を見ることができますが、前者は結合できません。

+0

"これは2回のパスを使用して、最初に必要なサイズを計算し、すべてをコピーします。 - 本当に?それは私が気づいていなかったリスト固有の最適化ですか?一般的なiterablesでは動作しません。 – user2357112

+0

ああ、まだタプルやリストでない場合は、入力からタプルを作り出します。 – user2357112

+1

あなたの 'bytes_join'リンクが壊れています。 ['string_join'](http://hg.python.org/cpython/file/2.7/Objects/stringobject.c#l1586)を試してください。 – user2357112

関連する問題