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

Coding style 迭代比线性码慢吗?哪一个更好?,coding-style,ruby,standards,Coding Style,Ruby,Standards,在过去的几天里,我有一个疑问,在用ruby编写代码时,线性代码是否比迭代更快更可取 让我举个例子。相同功能的代码块以两种不同的方式编写: 方式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,

在过去的几天里,我有一个疑问,在用ruby编写代码时,线性代码是否比迭代更快更可取

让我举个例子。相同功能的代码块以两种不同的方式编写:

方式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."

所以,我想知道哪一个更好、更可取?根据我的观点,我认为第二个需要更少的时间和记忆。但我想确认一下。

严格地说,是的,迭代涉及到开销。在您使用的任何语言中都会出现这种情况(尽管有些人使用编译器技巧来减少这种情况)。由于迭代和构建您定义的数组的成本,您的代码的第一个版本的运行速度可以忽略不计。此外,这座弦式建筑可能还会增加一小部分成本

也就是说,这是一个如此微小的差异,你必须非常挑剔地注意到,甚至关心这些。这是微不足道的。自己尝试基准测试,你不会注意到显著的差异


我不准备为了某种方法写10000行这样的话,你呢?我发现迭代看起来更干净,特别是对于非平凡的代码,并且在可读性和干净的代码方面更可取。更不用说了。

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

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

我想第二个会花更少的时间和记忆

别想了。看


这里有一个疯狂的想法:如果你想知道哪一个跑得更快,就跑他们,看看哪一个跑得更快

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

我意识到您的示例非常简单,不太可能在现实世界中出现,但从字面上看:

第一个示例将创建中间对象(字符串和数组),因此您可能会说实际上它将占用更多内存。但是,这些对象稍后将被垃圾收集,因此您将恢复内存。(如果定义了符号数组,则不会出现这种情况,因为符号不会被垃圾收集)

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

如果您是一个性能怪胎,那么您可能也应该在参数周围定义没有括号的方法,因为这将导致Ruby解释器创建的解析树变小

# slower
def meth(arg)
end

# faster
def meth arg
end
但是,把它当作一个合理的理由当然是愚蠢的


编辑:如果您正在寻找一个好的Ruby风格指南,请检查以下内容:

如果这两个选项中有一个明显更好,因此更可取,那么该语言不会同时提供这两个选项。一如既往,这取决于具体情况。你应该问的问题包括

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

正如你所见,答案相互矛盾,因此你必须理解你所做决策的背景,并正确权衡各种因素,以找出哪一个因素总体上是最好的。

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

第二个例子违反了原则,是一个小的维护问题



这个问题属于StackOverflow,它已经被问过并回答过了。对于给出的例子来说,这可能无关紧要。你能举出一个真实世界的例子来说明这个Q可能有意义吗?+1表示“不要思考。看”。证据总是胜过猜测。非常感谢@Michal提供更多的知识(括号和非括号的性能)
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)