我运行了一些基准测试,并且想知道为什么反转字符串并将其与自身进行比较似乎比比较单个字符要快。
反转字符串是最坏情况O(n)和比较O(n),导致O(n),除非比较同一个对象,它应该是O(1)。但是
str = "test"
str.reverse.object_id == str.object_id # => false
字符比较最坏情况是O(1)吗?我错过了什么?
修改
我提取并简化了问题,但这里是我运行的代码。
def reverse_compare(str)
str.reverse == str
end
def iterate_compare(str)
# can test with just str[0] != str[-1]
(str.length/2).times do |i|
return false if str[i] != str[-i-1]
end
end
require "benchmark"
n = 2000000
Benchmark.bm do |x|
str = "cabbbbbba" # best case single comparison
x.report("reverse_compare") { n.times do reverse_compare(str) ; a = "1"; end }
x.report("iterate_compare") { n.times do iterate_compare(str) ; a = "1"; end }
end
user system total real
reverse_compare 0.760000 0.000000 0.760000 ( 0.769463)
iterate_compare 1.840000 0.010000 1.850000 ( 1.855031)
答案 0 :(得分:2)
有两个因素支持反向方法:
看起来这两个因素比通过更好的算法获得的性能提升更大,但这是在ruby中完成的。
另请注意,在测试中,您不会测试随机字符串,而是测试特定字符串,这也非常短。如果你尝试更大的那个,那么ruby实现可能会更快。
答案 1 :(得分:0)
证明@SztupY的一些想法。如果你改变了一下代码,就像这样:
A
你会得到一些不同的结果:
def reverse_compare(str)
str.reverse == str
end
def iterate_compare(a, b)
a != b
end
require "benchmark"
n = 2_000_000
Benchmark.bm do |x|
str = "cabbbbbba" # best case single comparison
a = str[0]; b = str[-1]
x.report("reverse_compare") { n.times do reverse_compare(str) ; end }
x.report("iterate_compare") { n.times do iterate_compare(a, b) ; end }
end
所以,你现在可以猜到从String创建2个字符串对象需要一些时间。