我从过去很多天在我心中一个问题,而在红宝石写代码,是线性代码比迭代更快,最好?
让我有一个例子。 还有就是对于用两种不同的方式相同的功能代码块:
方法1:
['dog', 'cat', 'tiger'].each do |pet_name|
puts "I have many pets, one of them is #{pet_name}."
end
方式二:
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."
所以,我想知道哪一个更好,最好? 按我的看法,我认为第二人会花费更少的时间和内存。 但我想确认。
时序逻辑是速度更快(见倍低于基准),但几乎从来没有重要的。 的更清晰,更易于维护的代码应该总是被选中。 只有表现出的需求应该引起一个停止优化程序员,并开始优化机器。 通过论证,我的意思是衡量 - 你运行它,并发现它是太慢了。
第二个例子违反了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
和文字字符串的一部分。),你会介绍复制越少越好。
正如你看到的,回答相互矛盾,所以你必须明白你做决定的情况下,正确权衡的因素,以找出哪些是全场最佳。
严格地说,是的,有参与迭代的开销。 有将在您使用(尽管一些使用技巧编译器,以减少这)任何语言。 你的代码的第一个版本将运行一个微不足道的更快由于迭代的成本,并建立你定义的数组。 此外,该字符串的建设将可能增加成本的另一个小小的片。
话虽这么说,这是你必须非常挑剔的注意,甚至关心任何有关这这样一个微小的差别。 这是可以忽略不计。 尝试自己标杆它,你不会注意到一个显著差异。
我不准备写10000行这样一些方法,是吗? 我发现,迭代看起来会更加清晰,特别是对于非平凡的代码,并且往往是在可读性和干净的代码的优选。 更何况它更干 。