迭代比线性代码慢吗? 哪个更好?

从最近几天开始,我脑子里有一个问题,那就是在ruby中编写代码时,线性代码比迭代更快更好吗?

让我举个例子。 有两个不同方式的相同function代码块:

方式1:

['dog', 'cat', 'tiger'].each do |pet_name| puts "I have many pets, one of them is #{pet_name}." end 

方式2:

 puts "I have many pets, one of them is dog." puts "I have many pets, one of them is cat." puts "I have many pets, one of them is tiger." 

所以,我想知道哪一个更好,更可取? 根据我的观点,我认为第二个将花费更少的时间和记忆。 但我想证实一下。

顺序逻辑更快(参见下面的基准),但它几乎不重要。 应始终选择更清晰,更易维护的代码。 只有经过validation的需求才能导致程序员停止优化并开始优化机器。 通过演示,我的意思是测量 – 你运行它并发现它太慢了。

第二个例子违反了DRY(不要重复自己)原则,并且是一个小的维护问题。


 require 'benchmark' LOOPS = 100000 Benchmark.bm(10) do |x| x.report('iteration') do LOOPS.times do ['dog', 'cat', 'tiger'].each do |pet_name| "I have many pets, one of them is #{pet_name}." end end end x.report('sequence') do LOOPS.times do "I have many pets, one of them is dog." "I have many pets, one of them is cat." "I have many pets, one of them is tiger." end end end # => user system total real # => iteration 0.200000 0.000000 0.200000 ( 0.202054) # => sequence 0.010000 0.000000 0.010000 ( 0.012195) 

在这两种情况下,运行实际Ruby代码所花费的时间将完全由将文本打印到屏幕所花费的时间来控制。 请记住:控制台输出很真的很慢。 痛苦地慢。

由于在这两种情况下代码都会向屏幕打印相同数量的文本(实际上是相同的文本),因此噪声中可能会丢失任何可能存在或可能不存在的微小性能差异。

我认为第二个将花费更少的时间和记忆。

别想。 看。

这是一个疯狂的想法:如果你想知道哪一个运行得更快,运行它们,看看哪一个运行得更快!

调用函数,创建数组或创建循环总是有成本的。但是这就是为编程语言而构建的,所以回答你的问题:是的,第二个代码可能更快,纳秒可能。 但第一个代码更通用,你永远不知道什么时候你会买一个新的宠物。 它更有用,也许有人会给你他们的宠物清单,你会想谈谈它们吗? 总的来说说好 – 第二个代码明显更快,但首先是更好,更好。

我意识到你的例子非常简单,不太可能在现实世界中发生,但从字面上理解:

第一个例子将创建中间对象(字符串和数组),所以你可能会说它实际上需要更多的内存。 但是这些对象以后会被垃圾收集,所以你会回忆起你的记忆。 (如果您定义了符号数组,则不会出现这种情况,因为符号不是垃圾回收的)。

它也更快,因为它不需要在每次迭代期间从数组内部获取对象。 但差异显然是不明显的,不应该被考虑在内。 应该考虑的是这里的可读性。

如果你是一个性能狂,你应该在参数周围没有括号的情况下定义你的方法,因为这会导致Ruby解释器创建的较小的解析树。

 # slower def meth(arg) end # faster def meth arg end 

但考虑到它是一个有道理的理由当然是愚蠢的。

编辑:如果您正在寻找一个好的Ruby风格指南,请查看: https : //github.com/bbatsov/ruby-style-guide

如果这两个选项中的一个明显更好并因此更可取,那么该语言将不提供这两种选择。 一如既往,这取决于具体情况。 您应该要求决定的问题包括

  • 哪个解决方案更具可读性? (对于习惯性的Ruby程序员,第一个是。)可读性越高越好。
  • 哪种解决方案更快? (你只能通过测量来决定这一点。注意使用一个现实的例子 – 只有三只动物的时差可能无法可靠地测量。)越快越好。
  • 通过“展开”更惯用的版本引入了多少重复? (在这种情况下,不是很多 – 字符串文字的puts和部分。)你引入的重复越少越好。

如您所见,答案相互矛盾,因此您必须了解您正在做出的决定的背景,并正确权衡这些因素,以找出哪个是最佳的。

严格来说,是的,迭代涉及开销。 将使用您使用的任何语言(尽管有些使用编译器技巧来减少这种情况)。 由于迭代的成本以及构建您定义的数组,代码的第一个版本的运行速度可以忽略不计。 此外,字符串构建可能会增加另一小部分成本。

话虽如此,这是一个微小的差异,你必须非常挑剔注意,甚至关心任何这一点。 这可以忽略不计。 尝试自己进行基准测试,您将不会注意到显着差异。

我不准备用某种方法写出10,000行这样的行,是吗? 我发现迭代看起来更清晰,特别是对于非平凡的代码,并且在可读性和干净的代码方面通常是优选的。 更不用说它更干 。