RubyMoney/money — pull request #397 by mjc (2014-05-22 23:47:12+00:00)
Title: Performance improvements

After finding that this gem is an order of magnitude slower on JRuby than MRI, I sat down with a profiler.

This patch offers about 1.99x improvement on MRI, 1.85x on RBX, and makes JRuby 2.6x faster than MRI (for a total improvement of 41.4x!)

Further gains could be had from switching to strings from symbols or at least reducing the number of .to_s and .to_sym calls, but this is enough for me for now, and I couldn't easily get such a conversion to pass the specs.

I can squash these commits if necessary.

MRI 2.1.2 Before
----------
```
Benchmark.ips { |x| x.report('String#to_money') { '$1,234.56'.to_money } }
Calculating -------------------------------------
String#to_money 2474 i/100ms
-------------------------------------------------
String#to_money 27583.9 (±7.0%) i/s - 138544 in 5.051407s
```

MRI 2.1.2 After
----------
```
Benchmark.ips { |x| x.report('String#to_money') { '$1,234.56'.to_money } }
Calculating -------------------------------------
String#to_money 4515 i/100ms
-------------------------------------------------
String#to_money 55149.0 (±4.5%) i/s - 275415 in 5.003928s
```

Rubinius e8990e6b (warm JIT) Before
----------
```
Benchmark.ips { |x| x.report('String#to_money') { '$1,234.56'.to_money } }
Calculating -------------------------------------
String#to_money 2027 i/100ms
-------------------------------------------------
String#to_money 22651.9 (±2.4%) i/s - 113512 in 5.014017s
```

Rubinius e8990e6b (warm JIT) After
----------
```
Benchmark.ips { |x| x.report('String#to_money') { '$1,234.56'.to_money } }
Calculating -------------------------------------
String#to_money 3347 i/100ms
-------------------------------------------------
String#to_money 41777.7 (±2.5%) i/s - 210861 in 5.050445s
```

JRuby 1.7.12 (Warm JIT, indy off) Before
----------
```
Benchmark.ips { |x| x.report('String#to_money') { '$1,234.56'.to_money } }
Calculating -------------------------------------
String#to_money 345 i/100ms
-------------------------------------------------
String#to_money 3450.7 (±3.1%) i/s - 17250 in 5.004000s
```

JRuby 1.7.12 (Warm JIT, indy off) After
----------
```
Benchmark.ips { |x| x.report('String#to_money') { '$1,234.56'.to_money } }
Calculating -------------------------------------
String#to_money 12341 i/100ms
-------------------------------------------------
String#to_money 142865.7 (±1.9%) i/s - 715778 in 5.012000s
```

JRuby 9k rev 9228157 (Warm JIT, indy off) Before
----------
```
Benchmark.ips { |x| x.report('String#to_money') { '$1,234.56'.to_money } }
Calculating -------------------------------------
String#to_money 342 i/100ms
-------------------------------------------------
String#to_money 3465.0 (±1.6%) i/s - 17442 in 5.035000s
```

JRuby 9k rev 9228157 (Warm JIT, indy off) After
----------
```
Calculating -------------------------------------
String#to_money 12976 i/100ms
-------------------------------------------------
String#to_money 147934.4 (±3.2%) i/s - 739632 in 5.005000s
```