ruby - 为什么 == 比 eql 快?

标签 ruby string benchmarking equality

我在 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? 的实现有关,但这是由于以下事实Ruby 优化运算符(如 ==)以避免尽可能进行正常的方法查找。

我们可以通过两种方式验证这一点:

  • == 创建别名并调用它。您会得到与 eql? 相似的结果,因此比 == 慢。

  • 比较使用 send :==send :eql? ,你会得到相似的时间;速度差异消失了,因为 Ruby 只会使用优化直接调用运算符,而不是使用 send__send__

这是显示两者的代码:

require 'fruity'
first = "Woooooha"
second = "Woooooha"
class String
  alias same_value? ==
end

compare do
  with_operator   { first == second }
  with_same_value { first.same_value? second }
  with_eql        { first.eql? second }
end

compare do
  with_send_op    { first.send :==, second }
  with_send_eql   { first.send :eql?, second }
end

结果:

with_operator is faster than with_same_value by 2x ± 0.1
with_same_value is similar to with_eql
with_send_eql is similar to with_send_op

如果您好奇的话,运算符的优化在 insns.def 中.

注意:此答案仅适用于 Ruby MRI,例如,如果 JRuby/rubinius 中存在速度差异,我会感到惊讶。

关于ruby - 为什么 == 比 eql 快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10257096/

相关文章:

c# - 如何从 C# 中的文件路径列表中提取公共(public)文件路径

python - "End of statement expected "python中的字符串语法错误

php - MySQL 数据库访问速度主要受数据库限制,还是受用于访问它的语言限制?

c++ - Google 基准测试结果中显示的时间没有意义

ruby - 如何解决 PATH 中的 Insecure world writable dir/usr,Ruby 模式 040777 警告?

ruby LoadError : cannot load such file

arrays - 使用数组键进行哈希到哈希的简单哈希

ruby - 应用神经网络识别数字

string - 如何使用字符串作为数据在 Matlab 中绘图?

performance - IDE/编译器 PC 基准测试来比较我的 PC 性能?