Как дорого обходятся словари Python? - PullRequest
30 голосов
/ 13 сентября 2009

Как видно из названия, насколько дорогими являются словари Python? Создание, вставка, обновление, удаление, все это.

Асимптотические сложности времени интересны сами по себе, но также и как они сравниваются, например, с. кортежи или обычные списки.

Ответы [ 2 ]

44 голосов
/ 14 сентября 2009

dicts (точно так же, как set s, когда вам не нужно связывать значение с каждым ключом, а просто записывать, присутствует или отсутствует ключ), в значительной степени оптимизированы. Создание dict из N ключей или пар ключ / значение - O(N), выборка - O(1), амортизация - O(1) и т. Д. На самом деле не может сделать ничего существенно лучше для любого не крошечного контейнера!

Для крошечных контейнеров вы можете легко проверить границы с помощью timeit эталонных тестов. Например:

$ python -mtimeit -s'empty=()' '23 in empty'
10000000 loops, best of 3: 0.0709 usec per loop
$ python -mtimeit -s'empty=set()' '23 in empty'
10000000 loops, best of 3: 0.101 usec per loop
$ python -mtimeit -s'empty=[]' '23 in empty'
10000000 loops, best of 3: 0.0716 usec per loop
$ python -mtimeit -s'empty=dict()' '23 in empty'
10000000 loops, best of 3: 0.0926 usec per loop

это показывает, что проверка членства в пустых списках или кортежах быстрее, на целых 20-30 наносекунд, чем проверка членства в пустых наборах или диктовках; когда важна каждая наносекунда, эта информация может иметь отношение к вам. Поднимаясь немного ...:

$ python -mtimeit -s'empty=range(7)' '23 in empty'
1000000 loops, best of 3: 0.318 usec per loop
$ python -mtimeit -s'empty=tuple(range(7))' '23 in empty'
1000000 loops, best of 3: 0.311 usec per loop
$ python -mtimeit -s'empty=set(range(7))' '23 in empty'
10000000 loops, best of 3: 0.109 usec per loop
$ python -mtimeit -s'empty=dict.fromkeys(range(7))' '23 in empty'
10000000 loops, best of 3: 0.0933 usec per loop

Вы видите, что для контейнеров из 7 предметов (не считая интересующего) баланс производительности сместился, и теперь у диктовок и наборов есть преимущества на СТО наносекунд. Когда предмет интереса присутствует:

$ python -mtimeit -s'empty=range(7)' '5 in empty'
1000000 loops, best of 3: 0.246 usec per loop
$ python -mtimeit -s'empty=tuple(range(7))' '5 in empty'
1000000 loops, best of 3: 0.25 usec per loop
$ python -mtimeit -s'empty=dict.fromkeys(range(7))' '5 in empty'
10000000 loops, best of 3: 0.0921 usec per loop
$ python -mtimeit -s'empty=set(range(7))' '5 in empty'
10000000 loops, best of 3: 0.112 usec per loop

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

И так далее, и так далее - timeit упрощает запуск микро-эталонов (строго говоря, гарантированно только в тех чрезвычайно редких ситуациях, когда наносекунды имеют значение, но достаточно легко, что это не так). большие трудности для проверки ДРУГИХ случаев; -).

15 голосов
/ 13 сентября 2009

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

Выбор между списками и диктатами на основе производительности кажется странным: они делают разные вещи. Может быть, вы расскажете нам больше о проблеме, которую пытаетесь решить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...