我最近几天在脑海里有一个问题,即在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."
所以,我想知道哪一个更好,更可取?根据我的观点,我认为第二个将花费更少的时间和记忆。但我想证实。
答案 0 :(得分:3)
顺序逻辑更快(参见下面的基准),但它几乎不重要。应始终选择更清晰,更易维护的代码。只有演示需要才能导致程序员停止优化并开始优化机器。通过演示,我的意思是测量 - 你运行它并发现它太慢了。
第二个例子违反了DRY (Don't Repeat Yourself)原则,是一个小维护问题。
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)
答案 1 :(得分:1)
在这两种情况下,运行实际Ruby代码所花费的时间将完全由将文本打印到屏幕所花费的时间来控制。请记住:控制台输出慢。 真的慢。痛苦地慢。
由于在这两种情况下代码都会向屏幕打印相同数量的文本(事实上,相同的文本),因此可能存在或可能不存在的任何微小的性能差异都将是在噪音中迷失了。
我认为第二个将花费更少的时间和记忆。
别想。看。
这是一个疯狂的想法:如果你想知道哪一个运行得更快,运行它们,看看哪一个运行得更快!
答案 2 :(得分:0)
严格地说,是的,迭代涉及开销。将使用您使用的任何语言(尽管有些使用编译器技巧来减少这种情况)。由于迭代的成本以及构建您定义的数组,代码的第一个版本的运行速度可以忽略不计。此外,字符串构建可能会增加另一小部分成本。
话虽如此,这是一个微不足道的差异,你必须非常挑剔地注意到,甚至关心这一点。这可以忽略不计。尝试自己进行基准测试,你不会注意到显着的差异。
我不准备用某种方法写出10,000行代码,是吗?我发现迭代看起来更清晰,特别是对于非平凡的代码,并且在可读性和干净的代码方面通常是优选的。更不用说它更多DRY。
答案 3 :(得分:0)
调用函数,创建数组或创建循环总是有成本的。但是这就是为编程语言而构建的,所以回答你的问题:是的,第二个代码会更快,也许是纳秒。但是第一个代码更通用,你永远不知道什么时候你会买一个新的宠物。它更有用,也许有人会给你他们的宠物清单,你会想谈谈它们吗?一般而言 - 第二代码的速度明显更快,但首先是更好,更可取。
答案 4 :(得分:0)
我意识到你的例子很简单,不太可能在现实世界中发生,但从字面上理解:
第一个例子将创建中间对象(字符串和数组),所以你可能会说它实际上需要更多的内存。然而,这些对象将在以后进行垃圾收集,因此您将获得回忆。 (如果您定义了符号数组,则不会出现这种情况,因为符号不是垃圾回收的。)
它也更快,因为它不需要在每次迭代期间从数组内部获取对象。但差异显然是不明显的,不应该被考虑在内。应该考虑的是这里的可读性。
如果你是一个表演怪胎,你应该在参数周围没有括号的情况下定义你的方法,因为这会导致由Ruby解释器创建的较小的解析树。
# slower
def meth(arg)
end
# faster
def meth arg
end
但是考虑到它是正当理由当然会很愚蠢。
编辑:如果您正在寻找一个好的Ruby风格指南,请查看:https://github.com/bbatsov/ruby-style-guide
答案 5 :(得分:0)
如果这两个选项中的一个显然更好,因此更可取,那么该语言将不提供这两种选择。一如既往,这取决于具体情况。您应该要求决定的问题包括
puts
和字符串文字的一部分。)你引入的重复越少越好。如您所见,答案相互矛盾,因此您必须了解所做决定的背景,并正确权衡这些因素,以找出哪个是最佳的。