Код...
options.get(something, doThisMostOfTheTime)()
... похоже, что он должен быть быстрее, но на самом деле он медленнее, чем конструкция if
... elif
... else
, потому что он должен вызывать функцию, что может привести к значительным накладным расходам производительности в узком цикле.
Рассмотрим эти примеры ...
1.py
something = 'something'
for i in xrange(1000000):
if something == 'this':
the_thing = 1
elif something == 'that':
the_thing = 2
elif something == 'there':
the_thing = 3
else:
the_thing = 4
2.py
something = 'something'
options = {'this': 1, 'that': 2, 'there': 3}
for i in xrange(1000000):
the_thing = options.get(something, 4)
3.py
something = 'something'
options = {'this': 1, 'that': 2, 'there': 3}
for i in xrange(1000000):
if something in options:
the_thing = options[something]
else:
the_thing = 4
4.py
from collections import defaultdict
something = 'something'
options = defaultdict(lambda: 4, {'this': 1, 'that': 2, 'there': 3})
for i in xrange(1000000):
the_thing = options[something]
... и обратите внимание на количество процессорного времени, которое они используют ...
1.py: 160ms
2.py: 170ms
3.py: 110ms
4.py: 100ms
... используя время пользователя из time(1)
.
Вариант № 4 требует дополнительных затрат памяти на добавление нового элемента для каждого отдельного пропуска ключа, поэтому, если вы ожидаете неограниченное количество отдельных пропущенных клавиш, я бы выбрал вариант № 3, который по-прежнему является значительным улучшением. оригинальная конструкция.
sort
те вещи, на которых работает ваша цепочка if / else ..., чтобы все элементы, которым соответствует одно из условий, находились на одном конце, а все остальные - на другом? Если это так, вы можете увидеть, быстрее / элегантнее это или нет. Но помните, если нет проблем с производительностью, об оптимизации волноваться рано.