web-dev-qa-db-ja.com

python sys.internは何をし、いつ使用する必要がありますか?

私はintern関数に言及している辞書のメモリ管理について この質問 に出くわしました。それは正確に何をし、いつ使用されますか?

例を挙げると:

seenという名前のセットがあり、重複をチェックするために使用する(string1、string2)の形式のタプルが含まれている場合、(intern (string1)、intern(string2))パフォーマンスを向上させるメモリまたは速度?

45
pufferfish

Python ドキュメントから:

sys.intern(string)

「インターンされた」文字列のテーブルに文字列を入力し、インターンされた文字列を返します。これは文字列自体またはコピーです。文字列のインターンは、ディクショナリルックアップのパフォーマンスを少し向上させるのに役立ちます。ディクショナリ内のキーがインターンされ、ルックアップキーがインターンされる場合、キー比較(ハッシュ後)は、文字列比較の代わりにポインタ比較によって実行できます。通常、Pythonプログラムで使用される名前は自動的にインターンされ、モジュール、クラス、またはインスタンスの属性を保持するために使用されるディクショナリにはインターンされたキーがあります。

インターンされた文字列は不滅ではありません。その恩恵を受けるには、intern()の戻り値への参照を保持する必要があります。

説明

ドキュメントが示唆しているように、sys.intern関数はパフォーマンスの最適化に使用することを目的としています。

sys.intern関数は、interned文字列のテーブルを維持します。文字列をインターンしようとすると、関数はそれをテーブルで検索し、次のことを行います。

  1. 文字列が存在しない場合(まだインターンされていない場合)、関数はそれをテーブルに保存し、インターンされた文字列テーブルから返します。

    >>> import sys
    >>> a = sys.intern('why do pangolins dream of quiche')
    >>> a
    'why do pangolins dream of quiche'
    

    上記の例では、aはインターンされた文字列を保持します。表示されていなくても、sys.intern関数は'why do pangolins dream of quiche'文字列オブジェクトをインターン文字列テーブルに保存しています。

  2. 文字列が存在する(インターンされている)場合、関数はインターンされた文字列テーブルから文字列を返します。

    >>> b = sys.intern('why do pangolins dream of quiche')
    >>> b
    'why do pangolins dream of quiche'
    

    文字列'why do pangolins dream of quiche'は以前にインターンされていたため、すぐには表示されませんが、baと同じ文字列オブジェクトを保持するようになりました。

    >>> b is a
    True
    

    インターンを使用せずに同じ文字列を作成すると、同じ値を持つ2つの異なる文字列オブジェクトになります。

    >>> c = 'why do pangolins dream of quiche'
    >>> c is a
    False
    >>> c is b
    False
    

sys.internを使用することにより、同じ値を持つ2つの文字列オブジェクトを作成しないようにします。既存の文字列オブジェクトと同じ値を持つ2番目の文字列オブジェクトの作成を要求すると、以前の文字列オブジェクトへの参照を受け取ります。既存の文字列オブジェクト。このようにして、メモリを節約します。また、文字列オブジェクトの比較は、内容ではなく2つの文字列オブジェクトのメモリアドレスを比較することによって実行されるため、非常に効率的になりました。

62
user11617

基本的に、インターンはインターンされた文字列のコレクションで文字列を検索(または存在しない場合は格納)するため、すべてのインターンされたインスタンスは同じIDを共有します。この文字列を検索する1回限りのコストと引き換えに、比較を高速化し(比較では、各文字を比較するのではなく、IDを確認するだけでTrueを返すことができます)、メモリ使用量を削減します。

ただし、python will 自動的に小さい、または識別子のように見える文字列をインターンする であるため、文字列はすでに舞台裏でインターンされているため、改善されない場合があります。 。 例えば:

>>> a = 'abc'; b = 'abc'
>>> a is b
True

過去には、1つの欠点は、インターンされたストリングが永続的であったことでした。インターンされると、すべての参照が削除された後でも、文字列メモリが解放されることはありませんでした。しかし、これはpythonの最近のバージョンには当てはまらないと思います。

18
Brian

Pythonにはそのようなことはないので、彼らはキーワードinternについて話していませんでした。彼らは 必須ではない組み込み関数intern について話していました。 py3kのどれが sys.intern 。ドキュメントには徹底的な説明があります。

11
SilentGhost

文字列の正規インスタンスを返します。

したがって、等しい文字列インスタンスが多数ある場合は、メモリを節約できます。さらに、正規化された文字列を、同等ではなくIDで比較することもできます。

4
flybywire