使用cProfile:
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 17.834 17.834 <string>:1(<module>)
1 0.007 0.007 17.834 17.834 basher.py:5551(_refresh)
1 0.000 0.000 10.522 10.522 basher.py:1826(RefreshUI)
4 0.024 0.006 10.517 2.629 basher.py:961(PopulateItems)
211 1.494 0.007 7.488 0.035 basher.py:1849(PopulateItem)
231 0.074 0.000 6.734 0.029 {method 'sort' of 'list' objects}
215 0.002 0.000 6.688 0.031 bosh.py:4764(getOrdered)
1910 3.039 0.002 6.648 0.003 bosh.py:4770(<lambda>)
253 0.178 0.001 5.600 0.022 bosh.py:3325(getStatus)
1 0.000 0.000 5.508 5.508 bosh.py:4327(refresh)
1911 3.051 0.002 3.330 0.002 {method 'index' of 'list' objects}
1910 3.039 0.002 6.648 0.003 bosh.py:4770(<lambda>)
行令我困惑。在bosh.py:4770我有modNames.sort(key=lambda a: (a in data) and data.index(a))
,数据和modNames是列表。注意1911 3.051 0.002 3.330 0.002 {method 'index' of 'list' objects}
似乎来自这一行。
那为什么这么慢?我可以用任何方式重写这个sort()
,以便它的执行速度更快吗?
>>> True and 3
3
答案 0 :(得分:3)
正如YardGlassOfCode所述,它本身并不是lambda
本身很慢,而是lambda内部的O(n)操作很慢。 a in data
和data.index(a)
都是O(n)
operations,其中n
是data
的长度。作为对效率的额外侮辱,对index
的呼吁也重复了a in data
中所做的大部分工作。如果data
中的项目是可以播放的,那么您可以通过首先准备一个字典来大大提高速度:
weight = dict(zip(data, range(len(data))))
modNames.sort(key=weight.get) # Python2, or
modNames.sort(key=lambda a: weight.get(a, -1)) # works in Python3
这要快得多,因为each dict lookup is a O(1)
operation。
请注意,modNames.sort(key=weight.get)
依赖于None比较小于整数:
In [39]: None < 0
Out[39]: True
在Python3中,None < 0
会引发TypeError
。因此,当lambda a: weight.get(a, -1)
不在a
时,weight
用于返回-1。