Minor Change Proposal for Class 'Numeric'

Discussion in 'Ruby' started by Wolfgang Nádasi-Donner, Jan 22, 2007.

  1. Hi!

    I didn't find there a discussion about this here, so first a description of this
    (very) minor change proposal.

    I miss the "Sign function" in class "Numeric".

    It can simply be added by something like...

    class Numeric
    def sign
    self<0?-1:self>0?1:0
    end
    end

    ....but it should be much faster if be defined in the original class.

    This method will be used in several algorithms, so it should be available from
    my point of view.

    Wolfgang Nádasi-Donner
    Wolfgang Nádasi-Donner, Jan 22, 2007
    #1
    1. Advertising

  2. Wolfgang Nádasi-Donner wrote:
    > Hi!
    >
    > I didn't find there a discussion about this here, so first a description
    > of this (very) minor change proposal.
    >
    > I miss the "Sign function" in class "Numeric".
    >
    > It can simply be added by something like...
    >
    > class Numeric
    > def sign
    > self<0?-1:self>0?1:0
    > end
    > end
    >
    > ...but it should be much faster if be defined in the original class.
    >
    > This method will be used in several algorithms, so it should be
    > available from my point of view.


    Seconded.

    Vince
    --
    Vincent Fourmond, PhD student
    http://vincent.fourmond.neuf.fr/
    Vincent Fourmond, Jan 22, 2007
    #2
    1. Advertising

  3. Wolfgang Nádasi-Donner

    Phrogz Guest

    Wolfgang Nádasi-Donner wrote:
    > class Numeric
    > def sign
    > self<0?-1:self>0?1:0
    > end
    > end
    >
    > ...but it should be much faster if be defined in the original class.


    a) Why do you need it to be so fast? Two comparisons seems pretty
    lightweight to me!
    b) Why do you think it's generally useful? I think such a method would
    have helped me only once or twice in all my programming years.

    c) You can implement that more compactly (if not more efficiently) as:

    irb(main):001:0> class Numeric; def sign; self <=> 0; end; end
    => nil
    irb(main):002:0> -1.sign
    => -1
    irb(main):003:0> -5.sign
    => -1
    irb(main):004:0> 0.sign
    => 0
    irb(main):005:0> 3.sign
    => 1
    Phrogz, Jan 22, 2007
    #3
  4. Phrogz wrote:
    > Wolfgang Nádasi-Donner wrote:
    >> class Numeric
    >> def sign
    >> self<0?-1:self>0?1:0
    >> end
    >> end
    >>
    >> ...but it should be much faster if be defined in the original class.

    >
    > a) Why do you need it to be so fast? Two comparisons seems pretty
    > lightweight to me!


    You forget function lookup: there is three function lookup for this
    code. Hardcoded in C is way faster (with only one function lookup).

    Vince

    --
    Vincent Fourmond, PhD student
    http://vincent.fourmond.neuf.fr/
    Vincent Fourmond, Jan 22, 2007
    #4
  5. Wolfgang Nádasi-Donner

    Eric Hodel Guest

    On Jan 22, 2007, at 15:18, Vincent Fourmond wrote:
    > Phrogz wrote:
    >> Wolfgang N=E1dasi-Donner wrote:
    >>> class Numeric
    >>> def sign
    >>> self<0?-1:self>0?1:0
    >>> end
    >>> end
    >>>
    >>> ...but it should be much faster if be defined in the original class.

    >>
    >> a) Why do you need it to be so fast? Two comparisons seems pretty
    >> lightweight to me!

    >
    > You forget function lookup: there is three function lookup for this
    > code. Hardcoded in C is way faster (with only one function lookup).


    So you've benchmarked it and found that calling Numeric#sign takes up =20=

    a significant part of your runtime?

    Note that you can write this in C for about 5 extra lines using =20
    RubyInline.

    --=20
    Eric Hodel - - http://blog.segment7.net

    I LIT YOUR GEM ON FIRE!
    Eric Hodel, Jan 22, 2007
    #5
  6. Eric Hodel wrote:
    >>
    >> You forget function lookup: there is three function lookup for this
    >> code. Hardcoded in C is way faster (with only one function lookup).

    >
    > So you've benchmarked it and found that calling Numeric#sign takes up a
    > significant part of your runtime?


    No ;-) I just point out that a C implementation will be faster than a
    pure Ruby one. Then, if you rely heavily on it, well, it would count,
    wouldn't it ?

    But I mainly raised the point to provoke, I obviously got what I
    wanted, didn't I ;-)

    > Note that you can write this in C for about 5 extra lines using

    RubyInline.

    That definitely is a good idea !

    Cheers,

    Vince

    --
    Vincent Fourmond, PhD student
    http://vincent.fourmond.neuf.fr/
    Vincent Fourmond, Jan 22, 2007
    #6
  7. Wolfgang Nádasi-Donner

    Phrogz Guest

    Vincent Fourmond wrote:
    > > a) Why do you need it to be so fast? Two comparisons seems pretty
    > > lightweight to me!

    >
    > You forget function lookup: there is three function lookup for this
    > code. Hardcoded in C is way faster (with only one function lookup).


    I actually hadn't forgotten it, but (mistakenly) thought that < and >
    didn't have normal method overhead. So, the spaceship operator is
    actually more terse and faster:

    class Numeric
    def sign1; self < 1 ? -1 : self > 1 ? 1 : 0; end
    def sign2; self<=>0; end
    def sign3; 0; end
    end

    require 'benchmark'

    N = 1_000_000
    Benchmark.bmbm{ |x|
    x.report{
    N.times{ -5.sign1; 5.sign1; 0.sign1 }
    }
    x.report{
    N.times{ -5.sign2; 5.sign2; 0.sign2 }
    }
    x.report{
    N.times{ -5.sign3; 5.sign3; 0.sign3 }
    }
    x.report{
    N.times{ -5.abs; 5.abs; 0.abs }
    }
    }

    Rehearsal ------------------------------------
    3.391000 0.000000 3.391000 ( 3.421000)
    2.296000 0.000000 2.296000 ( 2.313000)
    1.610000 0.000000 1.610000 ( 1.609000)
    0.969000 0.000000 0.969000 ( 0.969000)
    --------------------------- total: 8.266000sec

    user system total real
    2.781000 0.000000 2.781000 ( 2.797000)
    2.250000 0.000000 2.250000 ( 2.249000)
    1.547000 0.000000 1.547000 ( 1.547000)
    0.922000 0.000000 0.922000 ( 0.922000)

    So, if we assume that it would be about as fast as #abs, then you're
    talking about saving about 1.3 MICRO seconds per call (on a 3GHz P4). I
    would be surprised (and interested) if saving that amount of time made
    a difference in someone's application, for this particular method.

    To put it in perspective:
    Suppose your Ruby program were controlling a game or simulation.
    Suppose you were getting 30fps. Suppose you were calling this method
    10,000 times PER FRAME. The difference between having this method
    rewritten in the core and using the spaceship operator gets you all the
    way to...30.9fps.
    Phrogz, Jan 22, 2007
    #7
  8. Phrogz schrieb:
    > b) Why do you think it's generally useful? I think such a method would
    > have helped me only once or twice in all my programming years.


    There is only one reason: It is a standard function used in mathematics and
    nearly everybody knows a function names "sign" or "sgn" from other programming
    languages.

    I think that the code for this method is still there in the kernel.

    > c) You can implement that more compactly (if not more efficiently) as:
    >
    > irb(main):001:0> class Numeric; def sign; self <=> 0; end; end


    It was only an example to describe what I mean. I have no suggestions for an
    implementation in the Ruby kernel.

    I only think, that a mathematical standard function should be available.

    Wolfgang Nádasi-Donner
    Wolfgang Nádasi-Donner, Jan 23, 2007
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. kbutterly
    Replies:
    1
    Views:
    349
    Jon Paal
    Feb 11, 2007
  2. Wolfgang Nádasi-Donner
    Replies:
    3
    Views:
    154
    Wolfgang Nádasi-Donner
    Jan 30, 2007
  3. Wolfgang Nádasi-Donner

    Minor Change Proposal for Classe 'UnboundMethod'

    Wolfgang Nádasi-Donner, Jan 19, 2007, in forum: Ruby
    Replies:
    0
    Views:
    112
    Wolfgang Nádasi-Donner
    Jan 19, 2007
  4. Wolfgang Nádasi-Donner
    Replies:
    1
    Views:
    98
    Wolfgang Nádasi-Donner
    May 15, 2007
  5. Dr John Stockton
    Replies:
    0
    Views:
    64
    Dr John Stockton
    Sep 12, 2003
Loading...

Share This Page