Форум сайта python.su
В некоторых случаях генераторы списков существенно обгоняют даже map+filter, не то что for, ввиду отсутствия необходимости вызывать функцию
def foo(x): return x % 2 def bar(x): return x > 10 def func1(): lst = [foo(x) for x in xrange(10000000) if bar(x)] def func2(): lst = filter(bar, map(foo, xrange(10000000))) t1 = timeit.Timer(func1, 'from __main__ import func1, foo') t2 = timeit.Timer(func2, 'from __main__ import func2, foo') print t1.timeit(1) print t2.timeit(1)
2.43812799454 2.16352391243
# -*- coding:utf-8 -*- import timeit .... def func1(): lst = [x % 2 for x in xrange(10000000) if x > 10] def func2(): lst = filter(bar, map(foo, xrange(10000000))) ....
0.842472791672 2.13915705681
def func1(): lst = [x % 2 for x in xrange(10000000) if x > 10] def func2(): lst = filter(lambda x: x > 10, map(lambda x: x % 2, xrange(10000000)))
0.844331979752 2.1546831131
Офлайн
user_uid = '10002' user_name = next(x.split(':')[0] for x in open('passwd.txt') if x.split(':')[2] == user_uid) print(user_name)
Офлайн
PooHc чего это ?
Имеется ввиду, что после того, как он найдет нужный элемент, итерация все равно будет выполнена до конца.
>>> import itertools >>> it = itertools.count() >>> next(it) 0 >>> next(it) 1 >>> next(it) 2 >>>
FishHookэто не из-за этого, во втором питоне эти функции создают списки, которые потом используются для перебора (создания итераторов)
В некоторых случаях генераторы списков существенно обгоняют даже map+filter, не то что for, ввиду отсутствия необходимости вызывать функцию
Отредактировано py.user.next (Дек. 9, 2013 00:14:30)
Офлайн
py.user.next
поэтому как filter(), так и map() нужно заменить на аналоги из itertools
и уже тогда сравнивать
import timeit from itertools import ifilter, imap def foo(x): return x % 2 def bar(x): return x > 0 def func1(): sum( [foo(x) for x in xrange(100000) if bar(x)] ) def func2(): sum( ifilter(bar, imap(foo, xrange(100000))) ) t1 = timeit.Timer(func1, 'from __main__ import func1, foo') t2 = timeit.Timer(func2, 'from __main__ import func2, foo') print t1.repeat(3, 10) print t2.repeat(3, 10)
[0.6189520359039307, 0.6175930500030518, 0.620582103729248] [0.568681001663208, 0.5698568820953369, 0.5771739482879639]
def func1(): sum( [x % 2 for x in xrange(100000) if x > 0] ) def func2(): sum( ifilter(lambda x: x > 0, imap(lambda x: x % 2, xrange(100000))) )
[0.20290303230285645, 0.2011399269104004, 0.19998598098754883] [0.5880811214447021, 0.5824930667877197, 0.5833539962768555]
Отредактировано Budulianin (Дек. 10, 2013 22:58:04)
Офлайн
py.user.next
это не из-за этого, во втором питоне эти функции создают списки, которые потом используются для перебора (создания итераторов)
поэтому как filter(), так и map() нужно заменить на аналоги из itertools
и уже тогда сравнивать
Офлайн
Budulianinну вот, что и требовалось доказать[0.6189520359039307, 0.6175930500030518, 0.620582103729248]
[0.568681001663208, 0.5698568820953369, 0.5771739482879639]
Budulianinво втором случае коды не эквивалентные
Как видно, вызов функций, тоже замедляет работу
Офлайн
py.user.next
во втором случае коды не эквивалентные
хочешь сравнить - возьми включение с функцией и включение без функции - их и сравнивай
Офлайн
py.user.nextНе согласен, в этом случае сравнивать надо не
нужно заменить на аналоги из itertools
и уже тогда сравнивать
[x for x ]
(x for x)
Офлайн
FishHookэто да, не думаю, что будут сильно различаться
Не согласен, в этом случае сравнивать надо не
Отредактировано py.user.next (Дек. 10, 2013 22:43:30)
Офлайн
py.user.next
На счёт того, что return и lst = не нужны для замеров, это понятно
А что позорного в return() ? Если интерпретатор это понимает
Офлайн