Project

General

Profile

Actions

Bug #7645

closed

BigDecimal#== slow when compared to true/false

Added by mathie (Graeme Mathieson) over 11 years ago. Updated over 11 years ago.

Status:
Closed
Target version:
-
ruby -v:
ruby 1.9.3p327 (2012-11-10 revision 37606) [x86_64-darwin12.2.0]
Backport:
[ruby-core:51213]

Description

I was doing a spot of profiling on a Ruby on Rails application with perftools.rb and spotted that one particular chunk of code was spending a lot (nearly 60% in some tests) of its time in BigDecimal#==. It turns out that, when writing a numeric attribute in ActiveRecord, it compares the value to both true and false, and that appears to be the source of the slowness. I've reproduced this with the following sample code:

require 'bigdecimal'

1_000_000.times do
  BigDecimal('3') == true
end

This snippet takes around 7 seconds to run on my Mac. If instead we compare with a number:

require 'bigdecimal'

1_000_000.times do
  BigDecimal('3') == 0
end

the runtime drops to ~1.2 seconds. This seems suboptimal. I'm struggling to follow through the BigDecimal source code, but the profile output indicates that BigDecimal#== is causing a NameError exception to be raised, which it's then catching and returning a valid result.

I've reported this issue to the Rails tracker here: https://github.com/rails/rails/issues/8673. While there's an easy workaround for ActiveRecord (I hope, anyway!), it does strike me that BigDecimalCmp() could short-circuit and return something sensible if the comparison value is true, false or nil?

This is my first bug report to Ruby core, so apologies if it's not quite up to scratch. If you need any more information from me, please do ask. Thank you!


Files

coerce.patch (1.27 KB) coerce.patch Eregon (Benoit Daloze), 01/02/2013 05:23 AM

Related issues 1 (0 open1 closed)

Related to Ruby master - Feature #7688: Error hiding with rb_rescue() on Comparable#==, #coerce and othersClosedEregon (Benoit Daloze)Actions
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0