Форум сайта python.su
PooHНу вроде бы тем, что “пересекался” с lt, le, eq, ne, gt, ge.
Чем он им помешал то?!
FishHookВ CPython itemgetter реализован на Cи
а чем, собственно, вариант с лямбдой хуже или лучше варианта с itemgetter
Pysrc/Modules/operator.c:325:/* itemgetter object
import timeit from operator import itemgetter def bench_lambda_key(buf): return sorted(buf, key=lambda x: (x[2],x[1],x[0])) def bench_lambda_auto_key(buf): return sorted(buf, key=lambda x: reversed(x)) def bench_itemgetter(buf): return sorted(buf, key=itemgetter(2,1,0)) def bench_keyfunc(buf): def keyfunc(x): return x[2],x[1],x[0] return sorted(buf, key=keyfunc) def measure(func, arg, times): print " %s %s" % (func.__name__, timeit.timeit(lambda: func(arg), number=times)) buffs = [[(i,i,i) for i in range(val,0,-1)] for val in (1000, 10000, 100000, 10000000)] print [(buf[0],buf[-1]) for buf in buffs] funcs = [func for name,func in globals().items() if name.startswith('bench_')] + [sorted] for buf in buffs: assert buf[-1] < buf[0] assert buf[-1] == (1,1,1) print "Buflen:", len(buf) for func in funcs: measure(func, buf, 3)
[((1000, 1000, 1000), (1, 1, 1)), ((10000, 10000, 10000), (1, 1, 1)), ((100000, 100000, 100000), (1, 1, 1)), ((10000000, 10000000, 10000000), (1, 1, 1))] Buflen: 1000 bench_itemgetter 0.00191706278265 bench_keyfunc 0.00287790388817 bench_lambda_key 0.00287559417398 bench_lambda_auto_key 0.00300378331185 sorted 0.000578968358455 Buflen: 10000 bench_itemgetter 0.0194231565786 bench_keyfunc 0.0218749181976 bench_lambda_key 0.0152325651224 bench_lambda_auto_key 0.0141616276402 sorted 0.00305036254814 Buflen: 100000 bench_itemgetter 0.130403383885 bench_keyfunc 0.179477496455 bench_lambda_key 0.178710286389 bench_lambda_auto_key 0.152915013296 sorted 0.040913892315 Buflen: 10000000 bench_itemgetter 14.2914632193 bench_keyfunc 19.6054661696 bench_lambda_key 19.6240705325 bench_lambda_auto_key 17.0308593215 sorted 4.21384796845
Buflen: 1000 bench_itemgetter 0.0267988439111 bench_keyfunc 0.00317316235289 bench_lambda_key 0.00303457950113 bench_lambda_auto_key 0.00624893175718 sorted 0.000451934077677 Buflen: 10000 bench_itemgetter 0.0240387354469 bench_keyfunc 0.0165294696434 bench_lambda_key 0.0145931592425 bench_lambda_auto_key 0.0314840991576 sorted 0.00325438730212 Buflen: 100000 bench_itemgetter 0.298087864608 bench_keyfunc 0.200838888196 bench_lambda_key 0.201263105703 bench_lambda_auto_key 0.219333539668 sorted 0.0355272538576 Buflen: 10000000 bench_itemgetter 48.9225983977 bench_keyfunc 30.2210835331 bench_lambda_key 29.9068399876 bench_lambda_auto_key 30.5330650985 sorted 4.42660690666
Отредактировано EBFE (Сен. 6, 2012 17:03:42)
Офлайн
Однако, просто sorted в 3 с лишним раза быстрее.
Офлайн
Ну и для любителей черезмерной оптимизации и LINQ
class LinqMixin(object): def OrderBy(self, arg, reverse=False): if isinstance(arg, int): arg = itemgetter(arg) elif isinstance(arg, str): arg = attrgetter(arg) # else lambda expression self.sort(key=arg, reverse=reverse) return self def OrderByDescending(self, arg): return self.OrderBy(arg, True) ThenBy = OrderBy ThenByDescending = OrderByDescending class CoolList(list, LinqMixin): pass def bench_linq(buf): l_buf = CoolList(buf) return l_buf.OrderBy(2).ThenBy(1).ThenBy(0) def bench_multiple_sort(buf): return sorted(sorted(sorted(buf, key=itemgetter(2)), key=itemgetter(1)), key=itemgetter(0))
Buflen: 100000
bench_linq 0.184998098335
bench_itemgetter 0.139423202773
bench_multiple_sort 0.197778516886
bench_lambda_auto_key 0.159128144483
bench_keyfunc 0.184526146735
bench_lambda_key 0.186749246648
sorted 0.0414897810546
Buflen: 10000000
bench_linq 19.0146251103
bench_itemgetter 14.8408456788
bench_multiple_sort 21.1929246525
bench_lambda_auto_key 17.6037073223
bench_keyfunc 20.4276331897
bench_lambda_key 20.6035298592
sorted 4.18729972853
Отредактировано EBFE (Сен. 6, 2012 23:34:03)
Офлайн
EBFEЧто это? Это такое матное слово для питонистов?
черезмерной оптимизации
Офлайн
odnochlenТо есть LINQ не такой продвинутый? Ничего, бывает. На жабе вообще похожего нет
OrderBy(2) - это не linq. Там аттрибуты указываются.
from collections import namedtuple # Person=namedtuple('Person', 'name age city') # b1 = CoolList([Person("Alice",21,"Redmond"),Person("Bob",20,"Boston"), Person("Nadine",21,"Denver")]) # >>> b1.OrderBy('age').ThenBy(lambda person: person.name) [Person(name='Alice', age=21, city='Redmond'), Person(name='Bob', age=20, city=' Boston'), Person(name='Nadine', age=21, city='Denver')] >>> b1.OrderBy('age').ThenBy(2) [Person(name='Bob', age=20, city='Boston'), Person(name='Nadine', age=21, city=' Denver'), Person(name='Alice', age=21, city='Redmond')] >>> b1.OrderBy(1).ThenBy(lambda person: person.name) [Person(name='Alice', age=21, city='Redmond'), Person(name='Bob', age=20, city=' Boston'), Person(name='Nadine', age=21, city='Denver')] >>> b1.OrderBy(lambda p: p.age).ThenBy('city') [Person(name='Bob', age=20, city='Boston'), Person(name='Nadine', age=21, city=' Denver'), Person(name='Alice', age=21, city='Redmond')]
Отредактировано EBFE (Сен. 7, 2012 02:50:17)
Офлайн
EBFEПросто на статических языках кортежи не есть гуд. Это питонистам по барабану, все равно поддержка IDE никакая.
То есть LINQ не такой продвинутый? Ничего, бывает. На жабе вообще похожего нет
Офлайн