【问题标题】:Why aren't Enumerators in Ruby (2.0 +) lazy by default?为什么默认情况下Ruby(2.0 +)中的枚举器不是惰性的?
【发布时间】:2014-02-13 19:44:10
【问题描述】:

为什么默认情况下 Ruby Enumerator 的行为不像 Enumerator::Lazy

在任何情况下有人想要使用非懒惰的Enumerator

已编辑:

下面对向后兼容性答案的评论,解释了为什么我还不相信:

假设我们在 Ruby 2.0.0 中添加了这些“重大”更改,这是一个主要版本,您在进行切换之前会彻底测试您的代码(特别是如果您要进行生产),不是吗?

编辑#2

我怀疑它与效率有关(如果有任何问题,请告诉我),所以我做了以下基准测试:(当然有些地方懒惰更好。这可能是为了证明为什么 Ruby 不是一直在使用懒惰?)

require 'fruity'
require 'prime'

compare do
  lazy { 
    g = Prime::EratosthenesGenerator.new; 1000.times { g.lazy.take(100).to_a } 
  }
  diligent { 
    g = Prime::EratosthenesGenerator.new; 1000.times { g.take(100).to_a } 
  }
end

我得到以下信息:(可能是由于调用了.lazy 方法而不是从一开始就使用Enumerator::Lazy?)

diligent is faster than lazy by 19.999999999999996% ± 1.0%

【问题讨论】:

  • 好问题! +1 ..顺便说一句我不知道
  • 哈哈 :-) 等待好的答案!
  • @ArupRakshit 您使用的客户端是否会在询问 ruby​​ 问题时通知您?
  • 哈哈.. 酷 :-) .. 我问是因为你太快了!
  • @uDaY 不是 Firefox 浏览器,没有插件..

标签: ruby ruby-2.0


【解决方案1】:

对于任何期望/依赖副作用的代码,将惰性设为默认值是breaking change

需要检查和测试以前对 Enumerator 的任何使用。 “最安全”/“理智”的方法只是保留非惰性行为作为默认值 - 同时提供惰性替代方法。

一些基本的/以前的设计决策不会那么容易被抛弃;早在 Ruby 1.8.7 就支持枚举器。

【讨论】:

  • 您有任何使用Enumerator::Lazy(或其增强版本)会破坏代码的示例吗?
  • @Abdo 我不需要为此声明提供示例(尽管创建一个人为的示例很简单)。相反,为了证明这将是一个非破坏性的 API 更改,我们需要查看所有使用 Enumerator 的现有 Ruby 代码,以表明它不是某人的精彩 [生产] 代码的情况会破裂。
  • 假设我们已将这些“重大”更改添加到 Ruby 2.0.0,这是一个主要版本,您将在进行切换之前彻底测试您的代码(特别是如果您要进行生产),没有?
  • @Abdo Touché。主要的 2.0 版本可以宣布它是一个重大变化,并做到了这一点。 ML 上可能会讨论为什么当时没有这样做。
  • 酷...所以你说这是一个“选择”的问题,Enumerable::Lazy 将来可以完全取代Enumerable
【解决方案2】:

可能是为了兼容性。最近引入了惰性枚举器,许多代码都依赖于非惰性枚举器。

【讨论】:

    猜你喜欢
    • 2013-04-09
    • 2016-04-22
    • 2018-09-16
    • 1970-01-01
    • 2016-05-25
    • 1970-01-01
    • 2010-11-02
    • 1970-01-01
    • 2015-10-22
    相关资源
    最近更新 更多