mirror of
https://github.com/satwikkansal/wtfpython
synced 2024-11-24 03:54:25 +01:00
Translate Bloating instance dict's example
This commit is contained in:
parent
4b4951d755
commit
9e2508ae6a
64
translations/README-ru.md
vendored
64
translations/README-ru.md
vendored
@ -3566,3 +3566,67 @@ KeyError: 1
|
||||
+ Этот процесс не обратим для конкретного экземпляра `dict`, и ключ даже не обязательно должен существовать в словаре. Поэтому попытка неудачного поиска имеет тот же эффект.
|
||||
|
||||
---
|
||||
|
||||
|
||||
### ▶ Раздуваем экземпляры словарей *
|
||||
<!-- Example ID: fe706ab4-1615-c0ba-a078-76c98cbe3f48 --->
|
||||
```py
|
||||
import sys
|
||||
|
||||
class SomeClass:
|
||||
def __init__(self):
|
||||
self.some_attr1 = 1
|
||||
self.some_attr2 = 2
|
||||
self.some_attr3 = 3
|
||||
self.some_attr4 = 4
|
||||
|
||||
|
||||
def dict_size(o):
|
||||
return sys.getsizeof(o.__dict__)
|
||||
|
||||
```
|
||||
|
||||
**Результат:** (Python 3.8, другие версии Python 3 могут немного отличаться)
|
||||
```py
|
||||
>>> o1 = SomeClass()
|
||||
>>> o2 = SomeClass()
|
||||
>>> dict_size(o1)
|
||||
104
|
||||
>>> dict_size(o2)
|
||||
104
|
||||
>>> del o1.some_attr1
|
||||
>>> o3 = SomeClass()
|
||||
>>> dict_size(o3)
|
||||
232
|
||||
>>> dict_size(o1)
|
||||
232
|
||||
```
|
||||
|
||||
Попробуем снова... В новом сессии интерпретатора:
|
||||
|
||||
```py
|
||||
>>> o1 = SomeClass()
|
||||
>>> o2 = SomeClass()
|
||||
>>> dict_size(o1)
|
||||
104 # как ожидается
|
||||
>>> o1.some_attr5 = 5
|
||||
>>> o1.some_attr6 = 6
|
||||
>>> dict_size(o1)
|
||||
360
|
||||
>>> dict_size(o2)
|
||||
272
|
||||
>>> o3 = SomeClass()
|
||||
>>> dict_size(o3)
|
||||
232
|
||||
```
|
||||
|
||||
Что заставляет эти словари раздуваться? И почему только созданные объекты также раздуваются?
|
||||
|
||||
#### 💡 Объяснение:
|
||||
+ CPython может повторно использовать один и тот же объект "keys" в нескольких словарях. Это было добавлено в [PEP 412](https://www.python.org/dev/peps/pep-0412/) с целью сокращения использования памяти, особенно в экземплярах словарей - где ключи (атрибуты экземпляра), как правило, общие для всех экземпляров.
|
||||
+ Эта оптимизация совершенно беспроблемна для экземпляров словарей, но она не работает, если нарушены некоторые условия.
|
||||
+ Словари с общим доступом к ключам не поддерживают удаление; если атрибут экземпляра удаляется, словарь становится "не общим", и общий доступ к ключам отключается для всех последующих экземпляров того же класса.
|
||||
+ Кроме того, если размер ключей словаря был изменен (из-за вставки новых ключей), они остаются общими *только* если они используются только одним словарем (это позволяет добавить много атрибутов в `__init__` самого первого созданного экземпляра, не вызывая "unshare"). Если на момент изменения размера существует несколько экземпляров, совместное использование ключей отключается для всех последующих экземпляров одного класса: CPython не может определить, используют ли ваши экземпляры один и тот же набор атрибутов, и решает отказаться от попытки поделиться ключами.
|
||||
+ Небольшой совет, если вы стремитесь уменьшить занимаемый программой объем памяти: не удаляйте атрибуты экземпляров и обязательно инициализируйте все атрибуты в `__init__`!
|
||||
|
||||
---
|
||||
|
Loading…
Reference in New Issue
Block a user