【问题标题】:Why php generator is slower than an array?为什么php生成器比数组慢?
【发布时间】:2014-08-19 08:43:10
【问题描述】:

根据文档中的 cmets:http://php.net/manual/en/language.generators.overview.php
我们可以看到,多亏了生成器,内存使用得到了巨大的改善(这很明显),但执行速度也慢了 2-3 倍——这对我来说并不是那么明显。

我们以牺牲时间为代价来提高内存使用率 - 这是不好的。
那么,为什么 php 生成器比数组慢?

感谢您的提示。

【问题讨论】:

  • 因为它必须运行代码来获取我们没有获取的内容以节省内存?
  • @NiettheDarkAbsol 是的,但在文档中它是作为时间问题的解决方案提供的:“生成器允许您编写使用 foreach 迭代一组数据的代码,而无需在其中构建数组内存,这可能会导致您超出内存限制,或需要大量的处理时间来生成"

标签: php performance foreach generator


【解决方案1】:

在进行很多次优化时,您必须在执行速度和内存使用量之间做出选择,即预先计算某些内容并将其存储或仅在需要时进行计算。

生成器允许您编写使用 foreach 进行迭代的代码 一组数据而不需要在内存中建立一个数组,这可能 导致您超出内存限制,或需要大量内存 生成的处理时间

该手册指的是您不会迭代使用生成器生成的所有结果的情况。速度优势在于您无需通过生成不需要的项目来浪费处理时间和内存。

生成器不是为替换数组而设计的。它们旨在作为实现Iterator 对象时减少样板代码的一种方式。生成器总是比数组慢,因为每次调用next() 时,生成器都必须生成值。

使用生成器,您可以做一些数组无法做到的有趣事情 - 例如,您可以表示无限序列(例如,您可以创建一个只接受 start 和 step 参数的 range 函数)。

我有点好奇,所以我对xrange(使用生成器实现,如PHP manual page)和内置的range 函数进行了快速比较。

我的机器上的结果(用 PHP 5.6 测试)是:

范围(1, 10000000, 1):

time: 5.2702
memory (byte): 1495269376

xrange(1, 10000000, 1):

time: 1.9010
memory (byte): 262144

请注意,我使用的“基准”代码遍历所有结果并进行简单的数学运算。如上所示,函数调用仅作为我正在测试的值的参考。与往常一样,使用像 YMMV 这样非常简单的基准测试。

【讨论】:

  • 供参考:3v4l.org/gXnic/perf#output,3v4l.org/kbnNo/perf#output 3v4l并没有提供很多内存,所以我只用了1.0e+5。
  • @SOFe 不错。使用更大的 N(即 100k),您会看到更大的差异(PHP 5.6 在两个版本中都不好)。 RangeGenerator
  • 现在我关心的是少量。我只有几个项目(通常在 10¹-10² 左右)要生成,但我需要非常频繁地生成。这使得大 N 对我的用例来说意义不大。
  • @SOFe 正如他们所说,过早优化是万恶之源。与所有优化一样,在进行更改之前测试和衡量您的用例的优化:)
  • 3v4l.org/J2Gpj/perf#output 3v4l.org/mUT3l/perf#output 这两个测试伴随着对 g() 的 100000 次调用,它要么创建一个 0-9 整数的数组,要么生成 0-9 个整数。从 PHP 7.2.4 开始,按用户时间计算,数组似乎比生成器快 60%。这符合 OP 的描述。
猜你喜欢
  • 1970-01-01
  • 2015-03-18
  • 1970-01-01
  • 2013-12-12
  • 2017-04-03
  • 2016-09-08
  • 2015-11-29
  • 2017-12-16
  • 2016-12-02
相关资源
最近更新 更多