[#3726] Fixnum#clone and Float#clone raise different exceptions — "David A. Black" <dblack@...>

Hi --

15 messages 2004/11/12
[#3749] Re: Fixnum#clone and Float#clone raise different exceptions — "David A. Black" <dblack@...> 2004/11/16

Hi --

[#3751] Re: Fixnum#clone and Float#clone raise different exceptions — Yukihiro Matsumoto <matz@...> 2004/11/16

Hi,

[#3752] Re: Fixnum#clone and Float#clone raise different exceptions — "David A. Black" <dblack@...> 2004/11/16

Hi --

[#3785] The latest 1.8.2 cvs prints parse error when starting extension compiling — Yukihiro Matsumoto <matz@...>

Hi,

13 messages 2004/11/23
[#3787] Re: The latest 1.8.2 cvs prints parse error when starting extension compiling — Johan Holmberg <holmberg@...> 2004/11/23

x.include? speed observation

From: Hugh Sasse Staff Elec Eng <hgs@...>
Date: 2004-11-17 18:39:44 UTC
List: ruby-core #3762
I wondered about implementing a fairly small set of  present/absent flags and 
about the resulting performance of various methods.  So I wrote
this:

------8<--------------
#!/usr/local/bin/ruby -w
#
# Attempt to compare the performance when searching in a set, array
# or a hash to find out which is better when serching.
#
#

require 'set'

symbols = [ :stilton, :gloucester, :limeswold, :camembert, :brie]

$times = 2000

(0...symbols.size).each do |c|
     eval "$asym#{c} = symbols.dup[0..#{c}]"
     eval "$ssym#{c} = Set.new(symbols.dup[0..#{c}])"
     eval "$hsym#{c} = Hash.new(); symbols.dup[0..#{c}].each{|x| $hsym#{c}[x] = 1}"
end

def asym
$times.times do
     $asym0.include?(:gloucester)
     $asym1.include?(:gloucester)
     $asym2.include?(:gloucester)
     $asym3.include?(:gloucester)
     $asym4.include?(:gloucester)
end
end

def ssym
($times+633).times do
     $ssym0.include?(:gloucester)
     $ssym1.include?(:gloucester)
     $ssym2.include?(:gloucester)
     $ssym3.include?(:gloucester)
     $ssym4.include?(:gloucester)
end
end

def hsym
$times.times do
     $hsym0.include?(:gloucester)
     $hsym1.include?(:gloucester)
     $hsym2.include?(:gloucester)
     $hsym3.include?(:gloucester)
     $hsym4.include?(:gloucester)
end
end

asym

ssym

hsym


------8<--------------

The 633 was just to check if Hash was being called for set.
The results 
ruby 1.8.2 (2004-11-06) [sparc-solaris2.9]
are, by means of this vim command:
:r! ruby -rprofile ~/progs/ruby/ArrayHashSet.rb
like this:

   %   cumulative   self              self     total
  time   seconds   seconds    calls  ms/call  ms/call  name
  42.84     8.14      8.14        3  2713.33  6293.33  Integer#times
  22.32    12.38      4.24    13165     0.32     0.43  Set#include?
  15.32    15.29      2.91    10000     0.29     0.39  Array#include?
  13.63    17.88      2.59    23165     0.11     0.11  Hash#include?
   5.26    18.88      1.00    10000     0.10     0.10  Kernel.==
   0.16    18.91      0.03        1    30.00    30.00  Profiler__.start_profile
   0.16    18.94      0.03        1    30.00    30.00  Kernel.require
   0.11    18.96      0.02       35     0.57     0.57  Fixnum#to_s
   0.05    18.97      0.01       15     0.67     4.00  Kernel.eval
   0.05    18.98      0.01       15     0.67     0.67  Set#add
   0.05    18.99      0.01        5     2.00     6.00  Set#initialize
   0.05    19.00      0.01       15     0.67     0.67  Array#initialize_copy
   0.05    19.01      0.01       15     0.67     1.33  Kernel.dup
   0.05    19.02      0.01        5     2.00     4.00  Set#merge
   0.00    19.02      0.00       10     0.00     0.00  Hash#initialize
   0.00    19.02      0.00        1     0.00     0.00  Fixnum#+
   0.00    19.02      0.00        1     0.00     0.00  Array#size
   0.00    19.02      0.00        1     0.00     0.00  Module#append_features
   0.00    19.02      0.00        2     0.00     0.00  Class#inherited
   0.00    19.02      0.00       50     0.00     0.00  Module#method_added
   0.00    19.02      0.00        1     0.00     0.00  Module#included
   0.00    19.02      0.00        1     0.00     0.00  Module#protected
   0.00    19.02      0.00        1     0.00  9150.00  Object#ssym
   0.00    19.02      0.00       15     0.00     0.00  Array#[]
   0.00    19.02      0.00       30     0.00     0.00  Hash#[]=
   0.00    19.02      0.00        5     0.00     0.00  Kernel.is_a?
   0.00    19.02      0.00        5     0.00     0.00  Module#==
   0.00    19.02      0.00        1     0.00     0.00  Module#include
   0.00    19.02      0.00        1     0.00  3430.00  Object#hsym
   0.00    19.02      0.00        1     0.00    80.00  Range#each
   0.00    19.02      0.00        3     0.00     0.00  Kernel.singleton_method_added
   0.00    19.02      0.00        1     0.00 19000.00  #toplevel
   0.00    19.02      0.00        5     0.00     0.00  Kernel.nil?
   0.00    19.02      0.00        1     0.00     0.00  String#==
   0.00    19.02      0.00        1     0.00  6300.00  Object#asym
   0.00    19.02      0.00       10     0.00     0.00  Kernel.class
   0.00    19.02      0.00       10     0.00     1.00  Array#each
   0.00    19.02      0.00       15     0.00     2.00  Class#new

----------------

My observations are these, for what they are worth, and explain why
I post this to Ruby-Core:

   * Sets seemed remarkably slow.  They don't need to hold values as
     well as keys, so if I hadn't realised that they were implemented
     by means of Hashes, I'd have expected them to be faster.  Is my
     expectation that sets should be fast too naive, or is there a
     case for re-implementing sets, to reflect this viewpoint?

   * Arrays were slower than Hashes.  I think I expected this, but it
     makes me wonder what could be done to speed up Arrays: would it
     make sense to have an Array subclass native to Ruby that was
     sorted, allowing binary search?

   * Hashes beat the lot.  Obviously the thing to go for at the
     moment.  If I don't need values, would using a singleton like
     nil make them more efficient at all, or is there anything else
     short of coding in C that I can do to optimise this?

I expect these observations are biased, being based on cases with a
few elements only, but I was trying to refactor switch statements,
without having to go to true polymorphism, because in my case a
small number of possible values will be tested many times.

If now isn't the time to consider these matters, hopefully having
this test and its results in the archive will benefit someone in the
furure, so feel free to deal with more pressing matters :-)

         Thank you,
         Hugh


In This Thread

Prev Next