【问题标题】:How to measure length of generator sequence (list comp vs generator expression)如何测量生成器序列的长度(列表比较与生成器表达式)
【发布时间】:2012-07-06 10:06:05
【问题描述】:

我有一个生成有限序列的生成器。确定 这个序列的长度我尝试了这两种方法:

 seq_len = sum([1 for _ in euler14_seq(sv)])  # list comp

 seq_len = sum(1 for _ in euler14_seq(sv))    # generator expression

sv 是序列的常量起始值。

我曾预计列表理解会更慢,并且 生成器表达式更快,但结果恰恰相反。

我认为第一个会占用更多内存,因为它 首先在内存中创建一个完整的列表 - 我也认为它会更慢的部分原因。

我的问题:这个观察可以推广吗?这是由于 第二个语句和第一个语句中涉及两个生成器?

我看过这些What's the shortest way to count the number of items in a generator/iterator?Length of generator outputIs there any built-in way to get the length of an iterable in python? 并看到了一些其他测量序列长度的方法,但我特别好奇 list comp 与生成器表达式的比较。

PS:当我决定解决 Euler Project #14 基于 昨天在 SO 上提出的问题。

(顺便说一下,在使用'_' 不需要变量值的地方)。

这是在 Windows 7 64 位下使用 Python 2.7.2(32 位)完成的

【问题讨论】:

  • 使用 '_' 是不需要的变量的规范 - 这是常见且被接受的做法 - 但恐怕其余的我无法帮助您。
  • 设置生成器需要做更多的工作。一旦序列足够长,生成器表达式应该更快
  • len(list(euler14_seq(sv))) 怎么样?此外,如果您正在测试这样的性能,您应该说明您正在测试的平台。特别是 Python 版本和操作系统以及可能的硬件信息。
  • 我认为简而言之,生成器会引入 __call__ 开销(在 Python 中可能会很慢),而 listcomp 不会,但这是一种直觉,我无法通过引用来支持.. .
  • ... 而且 listcomp 的语句更优化,因为执行的代码是静态的,而生成器可以随意冒泡并追求其他东西

标签: python python-2.7 generator list-comprehension sequences


【解决方案1】:

在这台计算机上,生成器表达式在 100,000 到 1,000,000 之间变得更快

$ python -m timeit "sum(1 for x in xrange(100000))"
10 loops, best of 3: 34.8 msec per loop
$ python -m timeit "sum([1 for x in xrange(100000)])"
10 loops, best of 3: 20.8 msec per loop
$ python -m timeit "sum(1 for x in xrange(1000000))"
10 loops, best of 3: 315 msec per loop
$ python -m timeit "sum([1 for x in xrange(1000000)])"
10 loops, best of 3: 469 msec per loop

【讨论】:

  • 我将sv 的值提高到了 1000000000,但 list comp 仍然更快(25 us/loop vs 30 us/loop)..
  • @Levon,我认为对 LC 的主要打击是内存分配。你的比我的快很多。对于繁忙的 Web 服务器,权衡可能会变得棘手,因为将这些临时列表存储在宝贵的 RAM 中可能比生成器使用的额外周期更昂贵
  • 也许,我确实有很多可用的 RAM。您在为生成器重新设置 cmets 中的观点也是一个很好的观点。还是有点不解。我将不得不再玩这个。谢谢。
【解决方案2】:

以下代码块应生成长度:

>>> gen1 = (x for x in range(10))
>>> len(list(gen1))
10

【讨论】:

  • 我不想混淆 len()sum() 以保持比较真实。我的问题的基本要点是弄清楚“列表组合”是否总是比“生成器表达式”快。
  • 谢谢..我会仔细看看(只是快速浏览一下)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-02
  • 1970-01-01
  • 2011-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-10
  • 2019-03-28
相关资源
最近更新 更多