Который обычно быстрее, урожай или добавление?

Я в настоящее время нахожусь в персональном проекте изучения, где я читал в базе данных XML. Я пишу функции, которые собирают данные, и я не уверен, каков был бы быстрый способ возвратить их.

Который обычно быстрее:

  1. yields, или
  2. несколько append()s в функции затем return следующее list?

Я был бы рад знать в какой ситуации где yields был бы быстрее, чем append()s или наоборот.

16
задан Kit 15 August 2010 в 14:34
поделиться

3 ответа

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.

18
ответ дан 30 November 2019 в 17:26
поделиться

Недавно я задал себе аналогичный вопрос, исследуя способы генерации всех перестановок списка (или кортежа) либо путем добавления в список, либо с помощью генератора, и нашел (для перестановок длиной 9, генерация которых занимает около секунды):

  • Наивный подход (перестановки - списки, добавление к списку, возвращение списка списков) занимает примерно в три раза больше времени, чем itertools.permutations
  • Использование генератора (т.е. yield ) снижает это примерно на. 20%
  • Использование генератора и создание кортежей является самым быстрым, примерно вдвое быстрее, чем itertools.permutations .

Возьмите с недоверием! Были очень полезны синхронизация и профилирование:

if __name__ == '__main__':
    import cProfile
    cProfile.run("main()")
8
ответ дан 30 November 2019 в 17:26
поделиться

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.

6
ответ дан 30 November 2019 в 17:26
поделиться
Другие вопросы по тегам:

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