Я в настоящее время нахожусь в персональном проекте изучения, где я читал в базе данных XML. Я пишу функции, которые собирают данные, и я не уверен, каков был бы быстрый способ возвратить их.
Который обычно быстрее:
yield
s, или append()
s в функции затем return
следующее list
?Я был бы рад знать в какой ситуации где yield
s был бы быстрее, чем append()
s или наоборот.
yield
имеет огромное преимущество в виде ленивости , а скорость обычно не лучшая причина для его использования. Но если он работает в вашем контексте, то нет причин не использовать его:
# yield_vs_append.py
data = range(1000)
def yielding():
def yielder():
for d in data:
yield d
return list(yielder())
def appending():
lst = []
for d in data:
lst.append(d)
return lst
Вот результат:
python2.7 -m timeit -s "from yield_vs_append import yielding,appending" "yielding()"
10000 loops, best of 3: 80.1 usec per loop
python2.7 -m timeit -s "from yield_vs_append import yielding,appending" "appending()"
10000 loops, best of 3: 130 usec per loop
По крайней мере, в этом очень простом тесте yield
быстрее, чем append.
Недавно я задал себе аналогичный вопрос, исследуя способы генерации всех перестановок списка (или кортежа) либо путем добавления в список, либо с помощью генератора, и нашел (для перестановок длиной 9, генерация которых занимает около секунды):
itertools.permutations
yield
) снижает это примерно на. 20% itertools.permutations
.Возьмите с недоверием! Были очень полезны синхронизация и профилирование:
if __name__ == '__main__':
import cProfile
cProfile.run("main()")
There is a even faster alternative to TH4Ck's yielding(). It is list comprehension.
In [245]: def list_comp():
.....: return [d for d in data]
.....:
In [246]: timeit yielding()
10000 loops, best of 3: 89 us per loop
In [247]: timeit list_comp()
10000 loops, best of 3: 63.4 us per loop
Of course it is rather silly to micro-benchmark these operations without knowing the structure of your code. Each of them are useful in difference situation. For example list comprehension is useful if you want to apply a simple operation that can be express as an single expression. Yield has a significant advantage for you to isolate the traversal code into a generator method. Which one is appropriate depends a lot on the usage.