Skip to content

String-based eval 7-13x slower in JRuby 10 vs JRuby 1.7 #9115

@tbsvttr

Description

@tbsvttr

Summary

All string-based eval variants (eval, instance_eval, class_eval, binding.eval) are significantly slower in JRuby 10 compared to JRuby 1.7. Block-based eval is unaffected.

Benchmark

require 'benchmark'

n = 50_000
obj = Object.new
klass = Class.new
b = binding

Benchmark.bm(20) do |x|
  x.report("eval string")       { n.times { eval("1 + 1") } }
  x.report("instance_eval str") { n.times { obj.instance_eval("1 + 1") } }
  x.report("instance_eval blk") { n.times { obj.instance_eval { 1 + 1 } } }
  x.report("class_eval str")    { n.times { klass.class_eval("1 + 1") } }
  x.report("class_eval blk")    { n.times { klass.class_eval { 1 + 1 } } }
  x.report("binding.eval")      { n.times { b.eval("1 + 1") } }
end

Results

Eval variant MRI 3.4.7 JRuby 1.7.27 JRuby 10.0.2.0 Regression (10 vs 1.7)
eval("...") 0.160s 0.031s 0.279s 9x slower
instance_eval str 0.156s 0.038s 0.287s 7.5x slower
class_eval str 0.159s 0.037s 0.285s 7.7x slower
binding.eval 0.140s 0.030s 0.381s 13x slower
instance_eval blk 0.004s 0.007s 0.004s ✓ OK
class_eval blk 0.004s 0.008s 0.004s ✓ OK

Key observations:

  • String-based eval: 7-13x regression from JRuby 1.7 to JRuby 10
  • Block-based eval: No regression, actually improved
  • JRuby 1.7 was actually faster than MRI for string eval, JRuby 10 is slower

Impact

This affects code using dynamic evaluation with strings, including:

  • DSLs that compile strings
  • Template engines
  • Dynamic method generation
  • Legacy code using string eval

Environment

  • JRuby 10.0.2.0 on Java 21 (Temurin 21.0.9)
  • JRuby 1.7.27 on Java 8 (Corretto 8.472)
  • MRI 3.4.7
  • macOS Darwin 25.1.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions