-
-
Notifications
You must be signed in to change notification settings - Fork 939
Open
Description
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") } }
endResults
| 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
Labels
No labels