{"issue":{"state":"open","created_at":"2011-12-15T04:20:09Z","updated_at":"2011-12-15T05:40:28Z","user":{"gravatar_id":"76f606af44d16f87957d45cd0b0fd484","id":43569,"url":"https://api.github.com/users/chuckremes","login":"chuckremes","avatar_url":"https://secure.gravatar.com/avatar/76f606af44d16f87957d45cd0b0fd484?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png"},"comments":2,"body":"While optimizing the perf of some code, I had an inkling that there might be a problem with comparing Fixnums via #== and the order in which they were compared. I wrote a short benchmark to see if there was an issue.\r\n\r\nLooks like RBX has a problem with #super, for one. Secondly, the Fixnum#== performance is nearly 3x slower on than on JRuby. Slow performance on a low-level activity like #== may have implications for overall runtime performance in regular \"real world\" code.\r\n\r\n```ruby\r\n\r\n# Test the performance of testing for equality in a class that includes\r\n# a module and calls super on it. See if there is any difference between\r\n# arg == Const and Const == arg for the runtimes.\r\n#\r\n\r\nrequire 'rubygems'\r\nrequire 'benchmark'\r\n\r\nA = 1\r\nB = 2\r\nC = 3\r\nD = 4\r\nE = 5\r\nF = 6\r\nG = 7\r\nH = 8\r\nI = 9\r\n\r\nmodule Foo1\r\n  def compare_it(val)\r\n    A == val ||\r\n    B == val\r\n  end\r\nend # Foo1\r\n\r\nmodule Foo2\r\n  def compare_it(val)\r\n    val == A ||\r\n    val == B\r\n  end\r\nend # Foo2\r\n\r\nclass Bar1\r\n  include Foo1\r\n  \r\n  def compare_it(val)\r\n    super ||\r\n    C == val ||\r\n    D == val ||\r\n    E == val ||\r\n    F == val ||\r\n    G == val ||\r\n    H == val ||\r\n    I == val\r\n  end\r\nend # Bar1\r\n\r\nclass Bar2\r\n  include Foo2\r\n  \r\n  def compare_it(val)\r\n    super ||\r\n    val == C ||\r\n    val == D ||\r\n    val == E ||\r\n    val == F ||\r\n    val == G ||\r\n    val == H ||\r\n    val == I\r\n  end\r\nend # Bar2\r\n\r\n@bar1 = Bar1.new\r\n@bar2 = Bar2.new\r\n\r\nIterations = 50_000_000\r\n\r\nBenchmark.bmbm(\"== order comparison for speed\".size) do |x|\r\n  x.report(\"bar1 A in super:\") do\r\n    Iterations.times { @bar1.compare_it(1) }\r\n  end\r\n\r\n  x.report(\"bar2 A in super:\") do\r\n    Iterations.times { @bar2.compare_it(1) }\r\n  end\r\n\r\n  x.report(\"bar1 C:\") do\r\n    Iterations.times { @bar1.compare_it(3) }\r\n  end\r\n\r\n  x.report(\"bar2 C:\") do\r\n    Iterations.times { @bar2.compare_it(3) }\r\n  end\r\n\r\n  x.report(\"bar1 I:\") do\r\n    Iterations.times { @bar1.compare_it(9) }\r\n  end\r\n\r\n  x.report(\"bar2 I:\") do\r\n    Iterations.times { @bar2.compare_it(9) }\r\n  end\r\n\r\nend\r\n```\r\n\r\nResults are:\r\n\r\n```ruby\r\nChuck-Remess-Mac-Pro:perf cremes$ rbx equals_bench.rb \r\nRehearsal ----------------------------------------------------------------\r\nbar1 A in super:              20.960131   0.018440  20.978571 ( 21.133859)\r\nbar2 A in super:              20.961552   0.015698  20.977250 ( 21.065954)\r\nbar1 C:                       20.079118   0.013177  20.092295 ( 20.149448)\r\nbar2 C:                       20.834044   0.017719  20.851763 ( 20.891548)\r\nbar1 I:                       25.436169   0.013837  25.450006 ( 25.513277)\r\nbar2 I:                       25.074366   0.012612  25.086978 ( 25.121529)\r\n----------------------------------------------------- total: 133.436863sec\r\n\r\n                                   user     system      total        real\r\nbar1 A in super:              18.532734   0.016796  18.549530 ( 18.572636)\r\nbar2 A in super:              19.075991   0.012712  19.088703 ( 19.120353)\r\nbar1 C:                       20.570250   0.008504  20.578754 ( 20.598505)\r\nbar2 C:                       21.011757   0.007455  21.019212 ( 21.043022)\r\nbar1 I:                       25.435906   0.015563  25.451469 ( 25.484010)\r\nbar2 I:                       25.324436   0.011867  25.336303 ( 25.381997)\r\nChuck-Remess-Mac-Pro:perf cremes$ rvm jruby\r\nChuck-Remess-Mac-Pro:perf cremes$ ruby --server equals_bench.rb \r\nRehearsal ----------------------------------------------------------------\r\nbar1 A in super:               7.706000   0.000000   7.706000 (  7.705000)\r\nbar2 A in super:               7.392000   0.000000   7.392000 (  7.393000)\r\nbar1 C:                        9.950000   0.000000   9.950000 (  9.950000)\r\nbar2 C:                       10.285000   0.000000  10.285000 ( 10.285000)\r\nbar1 I:                       17.860000   0.000000  17.860000 ( 17.860000)\r\nbar2 I:                       17.611000   0.000000  17.611000 ( 17.611000)\r\n------------------------------------------------------ total: 70.804001sec\r\n\r\n                                   user     system      total        real\r\nbar1 A in super:               7.981000   0.000000   7.981000 (  7.981000)\r\nbar2 A in super:               7.816000   0.000000   7.816000 (  7.816000)\r\nbar1 C:                       10.179000   0.000000  10.179000 ( 10.179000)\r\nbar2 C:                       10.234000   0.000000  10.234000 ( 10.235000)\r\nbar1 I:                       17.381000   0.000000  17.381000 ( 17.381000)\r\nbar2 I:                       17.510000   0.000000  17.510000 ( 17.509000)\r\n```","assignee":null,"id":2562962,"labels":[],"pull_request":{"patch_url":null,"html_url":null,"diff_url":null},"number":1452,"title":"Low-level #== is 3x slower on RBX than JRuby","html_url":"https://github.com/rubinius/rubinius/issues/1452","closed_at":null,"milestone":null,"url":"https://api.github.com/repos/rubinius/rubinius/issues/1452"},"action":"created","comment":{"created_at":"2011-12-15T05:40:27Z","updated_at":"2011-12-15T05:40:27Z","user":{"gravatar_id":"76f606af44d16f87957d45cd0b0fd484","id":43569,"url":"https://api.github.com/users/chuckremes","login":"chuckremes","avatar_url":"https://secure.gravatar.com/avatar/76f606af44d16f87957d45cd0b0fd484?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png"},"body":"Maybe. I modified the bench to do another test where it compares \"1 == val\", etc. and the numbers are pretty similar.\r\n\r\nAlso, like 99% of Ruby programmers, when I use a constant then I *really* mean for it to be constant. I guess I kind of assumed that constants were replaced at compile-time with their values, but I guess that wouldn't work since Ruby constants aren't really constant. <sigh>","id":3157080,"url":"https://api.github.com/repos/rubinius/rubinius/issues/comments/3157080"}}