【发布时间】:2012-04-21 07:20:50
【问题描述】:
我在 String 类的文档中读到,eql? 是一个严格的相等运算符,没有类型转换,== 是一个相等运算符,它试图将其第二个参数转换为字符串,以及 C 源代码此方法的代码确认:
eql?源代码:
static VALUE
rb_str_eql(VALUE str1, VALUE str2)
{
if (str1 == str2) return Qtrue;
if (TYPE(str2) != T_STRING) return Qfalse;
return str_eql(str1, str2);
}
==源代码:
VALUE
rb_str_equal(VALUE str1, VALUE str2)
{
if (str1 == str2) return Qtrue;
if (TYPE(str2) != T_STRING) {
if (!rb_respond_to(str2, rb_intern("to_str"))) {
return Qfalse;
}
return rb_equal(str2, str1);
}
return str_eql(str1, str2);
}
但是当我尝试对这些方法进行基准测试时,我很惊讶== 比eql? 快了高达 20%!
我的基准代码是:
require "benchmark"
RUN_COUNT = 100000000
first_string = "Woooooha"
second_string = "Woooooha"
time = Benchmark.measure do
RUN_COUNT.times do |i|
first_string.eql?(second_string)
end
end
puts time
time = Benchmark.measure do
RUN_COUNT.times do |i|
first_string == second_string
end
end
puts time
结果:
Ruby 1.9.3-p125:
26.420000 0.250000 26.670000 ( 26.820762)
21.520000 0.200000 21.720000 ( 21.843723)
Ruby 1.9.2-p290:
25.930000 0.280000 26.210000 ( 26.318998)
19.800000 0.130000 19.930000 ( 19.991929)
那么,当我为两个相似的字符串运行它时,谁能解释为什么更简单的eql? 方法比== 方法慢?
【问题讨论】:
-
微型基准测试并不容易做到,可能有很多事情会影响您的输出。当您开始基准测试时,您确定处理器处于最新状态吗?您是否尝试过更改基准测试的顺序?您是否尝试过多次,每次在
==和eql?之间切换?最后,eql?应该比==快(如果 C 代码是正确的)。 -
我能够确认这些结果。尝试过切换顺序,尝试过两者交替等等。结果非常一致,
==似乎比eql?快。 -
@mliebelt 我同意你的观点,
eql?必须比==更快或至少不低于==,但我试图改变基准测试的顺序。结果是一样的。我没有尝试每次都切换==和eql?,你能提供这种基准的例子吗? -
哎哟。我对你一年多没有得到答复并不感到惊讶。它看起来是一个简单的问题,但实际上非常!很高兴我偶然发现了这个问题。
标签: ruby string benchmarking equality