Найти - Пользователи
Полная версия: Прерывание цыкла генератора
Начало » Python для экспертов » Прерывание цыкла генератора
1 2 3 4
Budulianin
smoke853
В смысле какая скорость? в первом случае время выполнения = 0.755, во втором = 0.002, очевидно что второй вариант работает быстрее.

Ну и что ты посчитал ? Твоя функция вернула генератор, а не результат работы генератора. Естественно создать генератор быстрее. А вот когда потребуется, чтобы твой генератор выдал значение, потратится ещё время, на его вычисление.
smoke853
Budulianin
Естественно создать генератор быстрее. А вот когда потребуется, чтобы твой генератор выдал значение, потратится ещё время, на его вычисление.

Да, понятно что потратится еще время на его вычисление, допустим: n-e время потратится на создание генератора + n-е время потратится на вычисление, но я думаю что время выполнения будет все равно быстрее чем если бы использовался return или я ошибаюсь?
Budulianin
smoke853
Да, понятно что потратится еще время на его вычисление, допустим: n-e время потратится на создание генератора + n-е время потратится на вычисление, но я думаю что время выполнения будет все равно быстрее чем если бы использовался return или я ошибаюсь?

Если одна функция просто вычисляет и возвращает значение, а вторая создаёт генератор, вычисляет и возвращает значение. Где меньше действий ?

Или ты думаешь, что напишешь волшебное слово yield и всё взлетит ? :)

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


В задачи ТС, вообще нигде генератор ниразу не нужен. Ему просто нужно первое подходящее значение вернуть и всё. А ему зачем-то генераторы подавай.
smoke853
Budulianin
Или ты думаешь, что напишешь волшебное слово yield и всё взлетит ?
Ну примерно так и думал , конечно все не взлетит, но думал что в разы будет работать быстрее.
Budulianin
smoke853
Ну примерно так и думал , конечно все не взлетит, но думал что в разы будет работать быстрее.

Просто надо видеть противоречия, и не кушать их.
На твоём скрине, время выполнения “одних и тех” же операций очень отличаются.

Вторая функция, вроде бы делает “такие же” действия, НО работает в 375 раз быстрее, это уже должно насторожить.
py.user.next
>>> with open('/etc/passwd', encoding='utf-8') as fin:
...     line = next(filter(lambda s: s.split(':')[0] == 'ftp', fin))
... 
>>> line
'ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin\n'
>>>
для второго - itertools.ifilter()
Budulianin
py.user.next

filter перебирает все элементы

py.user.next
Budulianin
filter перебирает все элементы
нет, это итератор

>>> it = filter(None, [1, 2, 3])
>>> it
<filter object at 0x7fd71400ca50>
>>> next(it)
1
>>> next(it)
2
>>> next(it)
3
>>> next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>>
PooH
py.user.next
нет, это итератор
Имеется ввиду, что после того, как он найдет нужный элемент, итерация все равно будет выполнена до конца.
Budulianin
Budulianin
Вообще-то генератор списков это просто “синтаксический сахар” и по реализации ничем не отличается, от обычного for. Следовательно он работает с такой же скоростью.

Поправочка, чтобы никого в заблуждение не вводить.

Из Лутца:
“генераторы списков могут выполняться значительно быстрее (зачастую почти в два раза), чем
инструкции циклов for, потому что итерации выполняются со скоростью
языка С, а не со скоростью программного кода на языке Python. Такое преимущество в скорости особенно важно для больших объемов данных.”

Проверяем:

def func1():
     lst = [x for x in range(10000)]
def func2():
     lst = []
     for x in range(10000):
          lst.append(x)
t1 = timeit.Timer(func1, 'from __main__ import func1')
t2 = timeit.Timer(func2, 'from __main__ import func2')
t1.repeat(3, 1000)
[1.3615523760017822, 1.1045241789979627, 1.1151962050025759]
t2.repeat(3, 1000)
[2.1324967270011257, 2.1218632529999013, 2.120350769997458]

This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB