Что делает python sys.intern, и когда его следует использовать?

Я столкнулся с этим вопросом об управлении памятью словарей, в котором упоминается функция intern. Что именно он делает, и когда он будет использоваться?

Чтобы привести пример:

Если у меня есть набор под названием seen, который содержит кортежи в форме (string1, string2), которые я использую для проверки дубликатов, будет хранить (intern (string1), intern (string2) ) улучшить производительность wrt памяти или скорости?

Ответ 1

Из Документация Python 3:

sys.intern(string)

Введите строку в таблицу "интернированных" строк и верните интернированная строка - это сама строка или копия. Внутренние струны полезно получить небольшую производительность при поиске в словаре - если ключи в словаре интернированы, а ключ поиска интернирован, ключевые сравнения (после хэширования) могут быть сделаны с помощью сравнения указателя вместо сравнения строк. Обычно имена, используемые в Python программы автоматически интернированы, а словари, используемые для хранения атрибуты модуля, класса или экземпляра имеют интернированные ключи.

Интернированные строки не бессмертны; вы должны держать ссылку на возвращаемое значение intern() вокруг, чтобы извлечь выгоду из него.

Разъяснение:

Как показывает документация, функция sys.intern предназначена для использования оптимизации производительности.

Функция sys.intern поддерживает таблицу интернированных строк. Когда вы пытаетесь ставить строку, функция просматривает ее в таблице и:

  • Если строка не существует (еще не интернирована), функция сохраняет он в таблице и возвращает ее из таблицы интернированных строк.

    >>> 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' в таблице интернированных строк.

  • Если строка существует (была интернирована), функция возвращает ее из таблица интернированных строк.

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

    Даже если это не сразу видно, потому что строка 'why do pangolins dream of quiche' была интернирована раньше, b теперь содержит тот же строковый объект, что и a.

    >>> b is a
    True
    

    Если мы создаем одну и ту же строку без использования intern, мы получим два разных строковых объекта с одинаковым значением.

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

Используя sys.intern, вы гарантируете, что вы никогда не создадите два строковых объекта, имеющих одно и то же значение, - когда вы запрашиваете создание второго строкового объекта с тем же значением, что и существующий строковый объект, вы получаете ссылку на pre существующий строковый объект. Таким образом, вы сохраняете память. Кроме того, сравнение строковых объектов теперь очень эффективно, потому что оно выполняется путем сравнения адресов памяти двух строковых объектов, а не их содержимого.

Ответ 2

По существу intern просматривает (или сохраняет, если не присутствует) строку в коллекции интернированных строк, поэтому все интернированные экземпляры будут иметь один и тот же идентификатор. Вы продаете единовременную стоимость поиска этой строки для более быстрого сопоставления (сравнение может вернуть True после простой проверки подлинности, а не для сравнения каждого символа) и сокращение использования памяти.

Однако python будет автоматически ставить строки, которые являются маленькими или похожими на идентификаторы, так что вы можете обнаружить, что не получаете улучшения, потому что ваши строки уже интернированы за кулисами. Например:

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

В прошлом один недостаток заключался в том, что интернированные строки были постоянными. После интернирования строка памяти никогда не была освобождена даже после того, как все ссылки были удалены. Я думаю, что это больше не относится к более поздним версиям python.

Ответ 4

Он возвращает канонический экземпляр строки.

Поэтому, если у вас много экземпляров строк, которые равны, вы сохраняете память, и, кроме того, вы можете также сравнивать канонизированные строки с помощью идентичности вместо равенства, которое выполняется быстрее.

Ответ 5

Эта идея кажется вокруг нас на нескольких языках, включая Python, Java и т.д.

String Interning