Skip to content

Commit 4b4951d

Browse files
committed
Translate Slowing down dict lookups example
1 parent 00e420f commit 4b4951d

File tree

1 file changed

+36
-0
lines changed

1 file changed

+36
-0
lines changed

translations/README-ru.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3530,3 +3530,39 @@ def convert_list_to_string(l, iters):
35303530
> должен быть один - и желательно только один - очевидный способ сделать это.
35313531
35323532
---
3533+
3534+
3535+
### ▶ Замедляем поиск по `dict` *
3536+
<!-- Example ID: c9c26ce6-df0c-47f7-af0b-966b9386d4c3 --->
3537+
```py
3538+
some_dict = {str(i): 1 for i in range(1_000_000)}
3539+
another_dict = {str(i): 1 for i in range(1_000_000)}
3540+
```
3541+
3542+
**Результат:**
3543+
```py
3544+
>>> %timeit some_dict['5']
3545+
28.6 ns ± 0.115 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
3546+
>>> some_dict[1] = 1
3547+
>>> %timeit some_dict['5']
3548+
37.2 ns ± 0.265 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
3549+
3550+
>>> %timeit another_dict['5']
3551+
28.5 ns ± 0.142 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
3552+
>>> another_dict[1] # Пытаемся получить значение по несуществующему ключу
3553+
Traceback (most recent call last):
3554+
File "<stdin>", line 1, in <module>
3555+
KeyError: 1
3556+
>>> %timeit another_dict['5']
3557+
38.5 ns ± 0.0913 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
3558+
```
3559+
Почему одни и те же выражения становятся медленнее?
3560+
3561+
#### 💡 Объяснение:
3562+
3563+
+ В CPython есть общая функция поиска по словарю, которая работает со всеми типами ключей (`str`, `int`, любой объект ...), и специализированная для распространенного случая словарей, состоящих только из `str`-ключей.
3564+
+ Специализированная функция (названная `lookdict_unicode` в [исходный код CPython](https://github.com/python/cpython/blob/522691c46e2ae51faaad5bbbce7d959dd61770df/Objects/dictobject.c#L841)) знает, что все существующие ключи (включая искомый ключ) являются строками, и использует более быстрое и простое сравнение строк для сравнения ключей, вместо вызова метода `__eq__`.
3565+
+ При первом обращении к экземпляру `dict` с ключом, не являющимся `str`, он модифицируется, чтобы в дальнейшем для поиска использовалась общая функция.
3566+
+ Этот процесс не обратим для конкретного экземпляра `dict`, и ключ даже не обязательно должен существовать в словаре. Поэтому попытка неудачного поиска имеет тот же эффект.
3567+
3568+
---

0 commit comments

Comments
 (0)