Как дорого обходятся словари Python?

Попробуйте:

NSComparisonResult order = [[UIDevice currentDevice].systemVersion compare: @"3.1.3" options: NSNumericSearch];
if (order == NSOrderedSame || order == NSOrderedDescending) {
    // OS version >= 3.1.3
} else {
    // OS version < 3.1.3
}
30
задан ire_and_curses 13 September 2009 в 19:43
поделиться

2 ответа

dicts (точно так же, как устанавливает 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 наносекунд, чем проверка принадлежности к пустым наборам или dicts; когда важна каждая наносекунда, эта информация может быть актуальной для вас. Поднимемся немного вверх ...:

$ 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

dicts и sets не сильно выигрывают, но кортежи и list получают, хотя dicts и set остаются намного быстрее.

И так далее, и так далее - timeit упрощает выполнение микротестов (строго говоря, гарантируется только для тех чрезвычайно редких ситуаций, когда наносекунды ДЕЙСТВИТЕЛЬНО имеют значение, но, достаточно просто, чтобы проверить в ДРУГИХ случаях ;-).

46
ответ дан 27 November 2019 в 22:08
поделиться

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

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

15
ответ дан 27 November 2019 в 22:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: