为什么这个GenExp的性能比列表理解差?
-
24-09-2019 - |
题
我试图找到最快的方法来计算与特定过滤器匹配的列表中的项目数。在这种情况下,找到列表中有多少个奇数。
在这样做的同时,我对比较列表理解与等效生成器表达式的结果感到惊讶:
python -m timeit -s "L = xrange(1000000)" "sum([1 for i in L if i & 1])"
10 loops, best of 3: 109 msec per loop
python -m timeit -s "L = xrange(1000000)" "sum(1 for i in L if i & 1)"
10 loops, best of 3: 125 msec per loop
我还尝试过L是常规列表和不同的尺寸,但在所有情况下,列表理解都会获胜。
与ListComp相比,GenExp的做法是什么导致它较慢的,该列表COMP创建了一个带有100万个项目的新列表?
(顺便说一句,我发现的最快方法是: x = 1; len(filter(x.__and__, L))
. 。是的,我知道写这样的代码杀死了小猫,我为此而做的是这样)
解决方案
如果基本无限的内存可用(在微小的基准中总是如此,尽管通常不在现实世界中! - ),列表将倾向于优于发电机,因为它们只能分配一次,而在一个“大束”中(一个大型束)((没有内存碎片等),而发电机则需要(内部)额外的努力来避免通过保留堆栈框架状态以允许恢复执行来避免这种“大束”方法。
列表申请还是发电机的处理速度更快 在真实的程序中 取决于确切的记忆情况,包括碎片化,这是在“微基准”中无法准确复制的。 IOW,最后,如果您真正关心性能,则必须仔细基准(并单独介绍)实际程序,而不仅仅是“玩具”微基准,在一般情况下。
其他提示
试试:
function draw(id, clr, fill) {
var canvas = document.getElementById(id);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.fillStyle = clr;
ctx.fillRect (fill);
}
}
. 不隶属于 StackOverflow