Project

General

Profile

Actions

Feature #3667

closed

Speedup Date._parse and Date._strptime by using a Hash instead of a Date::Format::Bag

Added by jeremyevans0 (Jeremy Evans) almost 14 years ago. Updated about 13 years ago.

Status:
Rejected
Assignee:
-
Target version:
-
[ruby-core:31649]

Description

=begin
In date/format.rb, the Date::Format::Bag helper class is used to get a slightly nicer internal API, but it has a significant performance cost. This patch is a fairly mechanical change to using a plain Hash instead of a Date::Format::Bag (which it removes). For the following test code, I'm getting a 53% performance increase for Date.parse and a 24% increase for Date.strptime.

$ ruby -v
ruby 1.9.2dev (2010-07-11 revision 28618) [x86_64-openbsd4.7]

Date._parse

$ cat date_parse.rb
require 'date'
m = Date.method(:_parse)
d = '2010-10-20 18:43:46+08:00'
10000.times{m.call(d)}

$ time ruby date_parse.rb

real 0m1.217s
user 0m1.130s
sys 0m0.050s

$ time ruby -I date2 date_parse.rb

real 0m0.793s
user 0m0.760s
sys 0m0.030s

Date._strptime:

$ cat date_strptime.rb
require 'date'
m = Date.method(:_strptime)
d = '2010-10-20 18:43:46+08:00'
s = '%Y-%m-%d %H:%M:%S%z'
10000.times{m.call(d, s)}

$ time ruby date_strptime.rb

real 0m1.984s
user 0m1.980s
sys 0m0.000s

$ time ruby -I date2 date_strptime.rb

real 0m1.595s
user 0m1.550s
sys 0m0.040s

This patch should operate identically to the current version except that it may include keys with nil values in the returned hashes (I'm not sure that it does, but there is no check against it). If that isn't acceptable, there's two options. There could be a Hash#delete_if call to remove things with nil values (easier, probably worse performance), or the internal code to be modified to never assign nil values to the hash (possibly slightly more work, probably better performance). In either case I'd be happy to do the work.
=end


Files

date_format.patch (17.3 KB) date_format.patch lib/date/format.rb patch jeremyevans0 (Jeremy Evans), 08/08/2010 10:40 AM
Actions #1

Updated by kstephens (Kurt Stephens) almost 14 years ago

=begin
We've been running the hack below for a while... Jeremy's solution is more performant:

Date::Format::Bag#method_missing is a performance hog.

if true && defined?(Date::Format) && defined?(Date::Format::Bag)
class Date::Format::Bag
def method_missing(sel, *args) # , &block)
sel = sel.to_s
t = sel.dup
set = t.chomp!('=')
t = t.intern

   #
   # There appear to be no callers like:
   #
   #   e.foo(something)
   #
   # Thus do not interpret any arguments as
   # the *rest parameter since it creates Arrays 
   # that are never referenced in:
   # 
   #   def foo(*rest); @elem[:foo]; end
   #
   expr = <<"END"

class #{self.class}
def #{t}(); @elem[#{t.inspect}]; end
def #{t}=(arg); @elem[#{t.inspect}] = arg; end
end
END
# $stderr.puts " **** #{self.class}##{sel} =>\n#{expr}"
eval(expr)

   if set
     @elem[t] = args[0]
   else
     @elem[t]
   end
 end

end
end

=end

Actions #2

Updated by tadf (tadayoshi funaba) almost 14 years ago

  • Priority changed from Normal to 3

=begin

=end

Actions #3

Updated by tadf (tadayoshi funaba) almost 14 years ago

  • Status changed from Open to Rejected

=begin
adopted struct.
=end

Actions #4

Updated by jeremyevans0 (Jeremy Evans) almost 14 years ago

=begin
Tadayoshi Funaba,

Did you do any testing to see how the use of Struct affects performance? In my testing, while your use of Struct provides a modest speedup over the previous code, it's nowhere near as much of a speedup as using a plain hash.

$ ruby -v
ruby 1.9.2dev (2010-07-11 revision 28618) [x86_64-openbsd4.7]

Date._parse:

$ time ruby date_parse.rb

real 0m1.222s
user 0m1.180s
sys 0m0.040s

$ time ruby -I date-struct date_parse.rb

real 0m1.152s
user 0m1.060s
sys 0m0.090s

$ time ruby -I date-hash date_parse.rb

real 0m0.805s
user 0m0.740s
sys 0m0.060s

Date._strptime:

$ time ruby date_strptime.rb

real 0m2.023s
user 0m1.990s
sys 0m0.030s

$ time ruby -I date-struct date_strptime.rb

real 0m1.974s
user 0m1.950s
sys 0m0.020s

$ time ruby -I date-hash date_strptime.rb

real 0m1.611s
user 0m1.580s
sys 0m0.030s

Please consider reverting your Struct commit (#28953) and committing my patch for a plain hash.

Thank you,
Jeremy Evans
=end

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0