faster integer arithmetics & arbitrary precision floating number

Discussion in 'Ruby' started by David Garamond, Jan 12, 2004.

  1. 1. Is there a way in Ruby to speed up 32bit integer arithmetics (only
    involving numbers & sums up to 2^32-1)? I want to use Ruby for
    summarizing network traffic logs, but it's pathetically slow compared to
    Perl:

    $ time ruby -e'1000000.times{1073741823+1073741824}'

    real 0m23.693s
    user 0m5.720s
    sys 0m0.610s
    $ time perl -e'for(1..1000000){1073741823+1073741824}'

    real 0m1.142s
    user 0m0.320s
    sys 0m0.050s

    since 2**30 is already in the Bignum range.

    2. Doing arbitrary integer math is already very convenient in Ruby
    because of its automatic conversion. But Ruby still doesn't do seamless
    conversion to arbitrary floating point numbers:

    $ irb
    irb(main):001:0> 0.00000000000000001
    => 1.0e-17
    irb(main):002:0> 0.000000000000000001
    => 0.0

    Any chance Ruby will do this in the future? Or perhaps in the nearer
    future, include an arbitrary floating number package in its distribution
    (is there any? GMP is GPL so it potentially a problem license-wise).

    --
    dave
     
    David Garamond, Jan 12, 2004
    #1
    1. Advertising

  2. David Garamond wrote:

    > 1. Is there a way in Ruby to speed up 32bit integer arithmetics (only
    > involving numbers & sums up to 2^32-1)? I want to use Ruby for
    > summarizing network traffic logs, but it's pathetically slow compared
    > to Perl:
    >
    > $ time ruby -e'1000000.times{1073741823+1073741824}'
    >
    > real 0m23.693s
    > user 0m5.720s
    > sys 0m0.610s
    > $ time perl -e'for(1..1000000){1073741823+1073741824}'
    >
    > real 0m1.142s
    > user 0m0.320s
    > sys 0m0.050s


    i just tried to run this, and this is really quite discouraging indeed..
    :O/ even though i was personnally never hurt by ruby's speed (yet).

    emmanuel
     
    Emmanuel Touzery, Jan 12, 2004
    #2
    1. Advertising

  3. One idea would be to make a "FastInt" class that stores inegers as regular C
    int's. It could work like this:

    int1 = FastInt.new(1073741823)
    int2 = FastInt.new(073741824)

    1000000.times{ int1 + int2 }

    So addition would be done in C, which would be faster.

    Notice: If you create the integers about as often as you add them, the
    conversion from Ruby to C and back would more than compensate for any gains
    from C (I suspect).

    I would expec that this:

    1000000.times do
    int1 = FastInt.new(1073741823)
    int2 = FastInt.new(073741824)
    int1 + int2
    end


    would be even slower.


    Cheers,
    Daniel.


    On Tue, Jan 13, 2004 at 12:09:53AM +0900, David Garamond wrote:
    > 1. Is there a way in Ruby to speed up 32bit integer arithmetics (only
    > involving numbers & sums up to 2^32-1)? I want to use Ruby for
    > summarizing network traffic logs, but it's pathetically slow compared to
    > Perl:
    >
    > $ time ruby -e'1000000.times{1073741823+1073741824}'
    >
    > real 0m23.693s
    > user 0m5.720s
    > sys 0m0.610s
    > $ time perl -e'for(1..1000000){1073741823+1073741824}'
    >
    > real 0m1.142s
    > user 0m0.320s
    > sys 0m0.050s
    >
    > since 2**30 is already in the Bignum range.
    >
    > 2. Doing arbitrary integer math is already very convenient in Ruby
    > because of its automatic conversion. But Ruby still doesn't do seamless
    > conversion to arbitrary floating point numbers:
    >
    > $ irb
    > irb(main):001:0> 0.00000000000000001
    > => 1.0e-17
    > irb(main):002:0> 0.000000000000000001
    > => 0.0
    >
    > Any chance Ruby will do this in the future? Or perhaps in the nearer
    > future, include an arbitrary floating number package in its distribution
    > (is there any? GMP is GPL so it potentially a problem license-wise).
    >
    > --
    > dave
    >


    --
    Daniel Carrera | No trees were harmed in the generation of this e-mail.
    PhD student. | A significant number of electrons were, however, severely
    Math Dept. UMD | inconvenienced.
     
    Daniel Carrera, Jan 12, 2004
    #3
  4. David Garamond

    ts Guest

    >>>>> "E" == Emmanuel Touzery <> writes:

    E> David Garamond wrote:
    >> 1. Is there a way in Ruby to speed up 32bit integer arithmetics (only
    >> involving numbers & sums up to 2^32-1)? I want to use Ruby for
    >> summarizing network traffic logs, but it's pathetically slow compared
    >> to Perl:
    >>
    >> $ time ruby -e'1000000.times{1073741823+1073741824}'
    >>
    >> real 0m23.693s
    >> user 0m5.720s
    >> sys 0m0.610s

    [...]

    E> i just tried to run this, and this is really quite discouraging indeed..
    E> :O/ even though i was personnally never hurt by ruby's speed (yet).

    just use a faster cpu

    svg% time ruby -e'1000000.times{1073741823+1073741824}'

    real 0m2.638s
    user 0m2.631s
    sys 0m0.008s
    svg%


    Guy Decoux
     
    ts, Jan 12, 2004
    #4
  5. David Garamond wrote:

    > 1. Is there a way in Ruby to speed up 32bit integer arithmetics (only
    > involving numbers & sums up to 2^32-1)? I want to use Ruby for
    > summarizing network traffic logs, but it's pathetically slow compared
    > to Perl:
    >
    > $ time ruby -e'1000000.times{1073741823+1073741824}'
    >
    > real 0m23.693s
    > user 0m5.720s
    > sys 0m0.610s
    > $ time perl -e'for(1..1000000){1073741823+1073741824}'
    >
    > real 0m1.142s
    > user 0m0.320s
    > sys 0m0.050s
    >
    > since 2**30 is already in the Bignum range.


    i have the feeling (unconfirmed) that perl is optimising it away since
    the result is unused or the operation repeated or something. i created a
    file with 1000000 lines repeating the addition and perl is very slow too
    then (and ruby too).

    i'm not sure.

    emmanuel
     
    Emmanuel Touzery, Jan 12, 2004
    #5
  6. > >$ time perl -e'for(1..1000000){1073741823+1073741824}'
    > >
    > >real 0m1.142s
    > >user 0m0.320s
    > >sys 0m0.050s
    > >
    > >since 2**30 is already in the Bignum range.

    >
    > i have the feeling (unconfirmed) that perl is optimising it away since
    > the result is unused or the operation repeated or something. i created a
    > file with 1000000 lines repeating the addition and perl is very slow too
    > then (and ruby too).



    That seems likely.

    Which brings up another point, shouldn't ruby have such an optimization
    also?

    Yes, I know that you can redefine the Integer class so that + does something
    weird, which means that you don't know what each + does until you are
    actually there. But suppose that there were a Ruby flag where I "promise" I
    haven't done anything odd to the numeric classes, and it is safe to optimize
    them. Wouldn't that be a good idea?

    --
    Daniel Carrera | No trees were harmed in the generation of this e-mail.
    PhD student. | A significant number of electrons were, however, severely
    Math Dept. UMD | inconvenienced.
     
    Daniel Carrera, Jan 12, 2004
    #6
  7. David Garamond

    ts Guest

    >>>>> "E" == Emmanuel Touzery <> writes:

    E> i have the feeling (unconfirmed) that perl is optimising it away since
    E> the result is unused or the operation repeated or something. i created a
    E> file with 1000000 lines repeating the addition and perl is very slow too
    E> then (and ruby too).

    the P language make a constant (1073741823+1073741824) and compute it only
    once


    Guy Decoux
     
    ts, Jan 12, 2004
    #7
  8. ts wrote:
    > E> i just tried to run this, and this is really quite discouraging indeed..
    > E> :O/ even though i was personnally never hurt by ruby's speed (yet).
    >
    > just use a faster cpu


    reminds me of Perl's very powerful pragmas:

    use less time;
    use more cpu;

    --
    dave
     
    David Garamond, Jan 12, 2004
    #8
  9. David Garamond

    Guest

    On Tue, 13 Jan 2004, David Garamond wrote:

    > Date: Tue, 13 Jan 2004 00:09:53 +0900
    > From: David Garamond <lists@zara.6.isreserved.com>
    > Newsgroups: comp.lang.ruby
    > Subject: faster integer arithmetics & arbitrary precision floating number
    >
    > 1. Is there a way in Ruby to speed up 32bit integer arithmetics (only
    > involving numbers & sums up to 2^32-1)? I want to use Ruby for
    > summarizing network traffic logs, but it's pathetically slow compared to
    > Perl:
    >
    > $ time ruby -e'1000000.times{1073741823+1073741824}'
    >
    > real 0m23.693s
    > user 0m5.720s
    > sys 0m0.610s
    > $ time perl -e'for(1..1000000){1073741823+1073741824}'
    >
    > real 0m1.142s
    > user 0m0.320s
    > sys 0m0.050s
    >
    > since 2**30 is already in the Bignum range.


    if there is someway you can organized your problem into arrays (eg. collecting
    the item to sum into one), narray might be the way to go, it offer blindingly
    fast numerical operations:

    ~ > time ruby -r narray -e 'NArray.int(1000000)[true] = 1073741823+1073741824'

    real 0m0.025s
    user 0m0.010s
    sys 0m0.010s

    ~ > time perl -e'for(1..1000000){1073741823+1073741824}'

    real 0m0.128s
    user 0m0.130s
    sys 0m0.000s


    in fact, the operations are fast enough that you might simply be able to use
    normal ruby objects and ignore the Fixnum/Bignum distinction - which is a very
    useful (accurate) abstraction:

    ~ > irb -r narray
    irb(main):001:0> (na=NArray.object(1000000))[true] = 1073741823+1073741824
    => 2147483647

    irb(main):002:0> a=Time.now; p(na.sum); b=Time.now; b.to_f - a.to_f
    2147483647000000
    => 0.882834911346436

    not bad for summing a million numbers with arbitrary precision eh?

    -a
    --

    ATTN: please update your address books with address below!

    ===============================================================================
    | EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
    | PHONE :: 303.497.6469
    | ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
    | STP :: http://www.ngdc.noaa.gov/stp/
    | NGDC :: http://www.ngdc.noaa.gov/
    | NESDIS :: http://www.nesdis.noaa.gov/
    | NOAA :: http://www.noaa.gov/
    | US DOC :: http://www.commerce.gov/
    |
    | The difference between art and science is that science is what we
    | understand well enough to explain to a computer.
    | Art is everything else.
    | -- Donald Knuth, "Discover"
    |
    | /bin/sh -c 'for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done'
    ===============================================================================
     
    , Jan 12, 2004
    #9
  10. Emmanuel Touzery wrote:
    > i have the feeling (unconfirmed) that perl is optimising it away since
    > the result is unused or the operation repeated or something. i created a
    > file with 1000000 lines repeating the addition and perl is very slow too
    > then (and ruby too).


    do you mean you did:

    #!/usr/bin/{perl,ruby}
    1234567+123456;
    1234567+123456;
    1234567+123456;
    1234567+123456;
    1234567+123456;
    ...

    ?

    then have you factored out compilation overhead? I would wild-guess that
    Perl is slightly slower than Ruby, due to its complex syntaxes?

    --
    dave
     
    David Garamond, Jan 12, 2004
    #10
  11. David Garamond

    Mike Stok Guest

    In article <>,
    Emmanuel Touzery <> wrote:
    >David Garamond wrote:
    >
    >> 1. Is there a way in Ruby to speed up 32bit integer arithmetics (only
    >> involving numbers & sums up to 2^32-1)? I want to use Ruby for
    >> summarizing network traffic logs, but it's pathetically slow compared
    >> to Perl:
    >>
    >> $ time ruby -e'1000000.times{1073741823+1073741824}'
    >>
    >> real 0m23.693s
    >> user 0m5.720s
    >> sys 0m0.610s
    >> $ time perl -e'for(1..1000000){1073741823+1073741824}'
    >>
    >> real 0m1.142s
    >> user 0m0.320s
    >> sys 0m0.050s
    >>
    >> since 2**30 is already in the Bignum range.

    >
    >i have the feeling (unconfirmed) that perl is optimising it away since
    >the result is unused or the operation repeated or something. i created a
    >file with 1000000 lines repeating the addition and perl is very slow too
    >then (and ruby too).
    >
    >i'm not sure.


    You are correct about perl optimising away a constant -

    [mike@ratdog mike]$ perl -MO=Deparse -e 'for(1..1000000){1073741823+1073741824}'
    foreach $_ (1 .. 1000000) {
    '???';
    }
    -e syntax OK

    ??? is B::Deparse's way of showing something that's been optimised away.
    If you make perl do some work then it does slow down e.g.

    [mike@ratdog mike]$ time perl -e 'for(1..1000000){1073741823+1073741824}'
    0.12user 0.00system 0:00.26elapsed 45%CPU (0avgtext+0avgdata 0maxresident)k
    0inputs+0outputs (297major+36minor)pagefaults 0swaps
    [mike@ratdog mike]$ time perl -e 'for(1..1000000){$_+1073741824}'
    0.24user 0.00system 0:00.24elapsed 100%CPU (0avgtext+0avgdata 0maxresident)k
    0inputs+0outputs (300major+36minor)pagefaults 0swaps
    [mike@ratdog mike]$ perl -MO=Deparse -e 'for(1..1000000){$_+1073741824}'
    foreach $_ (1 .. 1000000) {
    $_ + 1073741824;
    }
    -e syntax OK

    Hope this helps,

    Mike

    --
    | The "`Stok' disclaimers" apply.
    http://www.stok.co.uk/~mike/ | GPG PGP Key 1024D/059913DA
    | Fingerprint 0570 71CD 6790 7C28 3D60
    http://www.exegenix.com/ | 75D2 9EC4 C1C0 0599 13DA
     
    Mike Stok, Jan 12, 2004
    #11
  12. "Daniel Carrera" <> schrieb im Newsbeitrag
    news:...
    >
    > One idea would be to make a "FastInt" class that stores inegers as

    regular C
    > int's. It could work like this:
    >
    > int1 = FastInt.new(1073741823)
    > int2 = FastInt.new(073741824)
    >
    > 1000000.times{ int1 + int2 }
    >
    > So addition would be done in C, which would be faster.
    >
    > Notice: If you create the integers about as often as you add them, the
    > conversion from Ruby to C and back would more than compensate for any

    gains
    > from C (I suspect).
    >
    > I would expec that this:
    >
    > 1000000.times do
    > int1 = FastInt.new(1073741823)
    > int2 = FastInt.new(073741824)
    > int1 + int2
    > end
    >
    >
    > would be even slower.


    Of course you would define FastInt#add which adds something to the current
    instance, removing the overhead of object creation.

    Cheers

    robert

    >
    >
    > Cheers,
    > Daniel.
    >
    >
    > On Tue, Jan 13, 2004 at 12:09:53AM +0900, David Garamond wrote:
    > > 1. Is there a way in Ruby to speed up 32bit integer arithmetics (only
    > > involving numbers & sums up to 2^32-1)? I want to use Ruby for
    > > summarizing network traffic logs, but it's pathetically slow compared

    to
    > > Perl:
    > >
    > > $ time ruby -e'1000000.times{1073741823+1073741824}'
    > >
    > > real 0m23.693s
    > > user 0m5.720s
    > > sys 0m0.610s
    > > $ time perl -e'for(1..1000000){1073741823+1073741824}'
    > >
    > > real 0m1.142s
    > > user 0m0.320s
    > > sys 0m0.050s
    > >
    > > since 2**30 is already in the Bignum range.
    > >
    > > 2. Doing arbitrary integer math is already very convenient in Ruby
    > > because of its automatic conversion. But Ruby still doesn't do

    seamless
    > > conversion to arbitrary floating point numbers:
    > >
    > > $ irb
    > > irb(main):001:0> 0.00000000000000001
    > > => 1.0e-17
    > > irb(main):002:0> 0.000000000000000001
    > > => 0.0
    > >
    > > Any chance Ruby will do this in the future? Or perhaps in the nearer
    > > future, include an arbitrary floating number package in its

    distribution
    > > (is there any? GMP is GPL so it potentially a problem license-wise).
    > >
    > > --
    > > dave
    > >

    >
    > --
    > Daniel Carrera | No trees were harmed in the generation of this e-mail.
    > PhD student. | A significant number of electrons were, however,

    severely
    > Math Dept. UMD | inconvenienced.
    >
    >
    >
     
    Robert Klemme, Jan 12, 2004
    #12
  13. wrote:
    > in fact, the operations are fast enough that you might simply be able to use
    > normal ruby objects and ignore the Fixnum/Bignum distinction - which is a very
    > useful (accurate) abstraction:
    >
    > ~ > irb -r narray
    > irb(main):001:0> (na=NArray.object(1000000))[true] = 1073741823+1073741824
    > => 2147483647
    >
    > irb(main):002:0> a=Time.now; p(na.sum); b=Time.now; b.to_f - a.to_f
    > 2147483647000000
    > => 0.882834911346436
    >
    > not bad for summing a million numbers with arbitrary precision eh?


    Nice! I can surely try clustering the numbers into sizable bites of
    Narray's before summing them up together.

    Thanks,
    --
    dave
     
    David Garamond, Jan 12, 2004
    #13
  14. David Garamond

    GGarramuno Guest

    David Garamond <lists@zara.6.isreserved.com> wrote in message news:<4002C471.1070507@zara.6.isreserved.com>...

    >
    > then have you factored out compilation overhead? I would wild-guess that
    > Perl is slightly slower than Ruby, due to its complex syntaxes?


    No, Perl is much faster than ruby for these sort of operations. Where
    Perl's speed suffers is in its OO (lots of nested classes can bring
    Perl down to its knees not to mention make the code very hard to deal
    with).

    Python2.2 is now an extremely good compromise for both, as it has
    great performance for simple things and it scales very well on complex
    projects. But I cannot stand its syntax, personally.

    Ruby is, for these type of operations, quite slow. It is somewhat
    akin to the old python1.5 overall. Ruby is in my opiniong the
    language that has the nicest syntax of them all, but both its speed
    and library base is not on par with others.


    In the python mailing list someone recently sent out a mail with a
    silly benchmark like that (which I ported to perl and ruby, too).
    "Nine Language Performance Round-up: Benchmarking Math & File I/O"
    http://www.osnews.com/story.php?news_id=5602

    This benchmark is not that great as it does not measure that many
    other areas of a language that you use in real code, but I guess it is
    okay if you want to get an idea of arithmetic speed.

    The top performer on that benchmark from the scripting languages is
    C#. And I was quite surprised that microsoft did something decent
    this time around (albeit C# is perhaps closer to C++ in philosophy and
    syntax than to a scripting language such as perl, ruby or python).

    On the machine I am on (XP) (and reducing the # of iterations of each
    one), I got:

    C#: 560 milliseconds
    Perl5.8.1: 5.08 sec.
    Python2.2.3: 6.07115513285 sec.
    Ruby1.8: 14.170000 sec.

    Indeed, Ruby seems particularly bad with normal integer arithmetic.

    Here's the not very scientific code for perl and ruby I used which I
    ported from python (you can get the rest from the guy's website to
    test). Since ruby deals with int/longs/bignums transparently, I am
    not sure the test below is a good example, thou of long behavior. But
    it does give you a rough idea where ruby stands in overall number
    crunching performance.


    #! /usr/bin/ruby

    require "benchmark"
    include Benchmark


    intMax = 10000000000 # 1B
    doubleMin = 10000000000.0 # 10B
    doubleMax = 11000000000.0 # 11B
    longMin = 10000000000 # 10B
    longMax = 11000000000 # 11B
    trigMax = 10000000.0 # 10M
    ioMax = 1000000 # 1M

    # I used these numbers to test as the orig. ones take too long
    intMax = 10000000 # 1B
    doubleMin = 10000000.0 # 10B
    doubleMax = 11000000.0 # 11B
    longMin = 10000000 # 10B
    longMax = 11000000 # 11B
    trigMax = 100000.0 # 10M
    ioMax = 10000 # 1M


    def intArithmetic(intMax)

    i = 1
    intResult = 1
    while i < intMax
    intResult = intResult - i
    i = i + 1
    intResult = intResult + i
    i = i + 1
    intResult = intResult * i
    i = i + 1
    intResult = intResult / i
    i = i + 1
    end
    print " i:", i, "\n"
    print " intResult:", intResult, "\n"
    end


    def doubleArithmetic(doubleMin, doubleMax)

    i = doubleMin
    doubleResult = doubleMin
    while i < doubleMax
    doubleResult = doubleResult - i
    i = i + 1.0
    doubleResult = doubleResult + i
    i = i + 1.0
    doubleResult = doubleResult * i
    i = i + 1.0
    doubleResult = doubleResult / i
    i = i + 1.0
    end
    print " i:", i, "\n"
    print " doubleResult:", doubleResult, "\n"
    end


    def longArithmetic(longMin, longMax)

    i = longMin
    longResult = longMin
    while i < longMax
    longResult = longResult - i
    i = i + 1
    longResult = longResult + i
    i = i + 1
    longResult = longResult * i
    i = i + 1
    longResult = longResult / i
    i = i + 1
    end
    print " i:", i, "\n"
    print " Result:", longResult, "\n"
    end


    def trig(trigMax)
    i = 1.0
    sine = 0.0
    cosine = 0.0
    tangent = 0.0
    logarithm = 0.0
    squareRoot = 0.0

    while i < trigMax
    sine = Math.sin(i)
    cosine = Math.cos(i)
    tangent = Math.tan(i)
    logarithm = Math.log10(i)
    squareRoot = Math.sqrt(i)
    i = i + 1.0
    end
    print " i:", i, "\n"
    print " sine:", sine, "\n"
    print " cosine:", cosine, "\n"
    print " tangent:", tangent, "\n"
    print " logarithm:", logarithm, "\n"
    print " squareRoot:", squareRoot, "\n"
    end


    def io(ioMax)
    fileName = "TestRuby.txt"
    myString = "abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefgh\n"

    linesToWrite = [myString]
    for i in 2..ioMax
    linesToWrite.push( myString )
    end

    file = File.open(fileName, 'w')
    file.puts(linesToWrite)
    file.close()

    file = File.open(fileName, 'r')
    readLines = file.readlines()
    file.close()
    print "write=",linesToWrite.length()
    print " read=",readLines.length()
    end


    # Main program begins here

    puts "Start Ruby benchmark"

    t = 0
    benchmark(" " + CAPTION, 7, FMTSTR) do |x|
    t = x.report("intArithmetic") { intArithmetic(intMax) }
    t += x.report("doubleArithmetic") { doubleArithmetic(doubleMin,
    doubleMax) }
    t += x.report("longArithmetic") { longArithmetic(longMin, longMax)
    }
    t += x.report("trig") { trig(trigMax) }
    t += x.report("io") { ioTime = io(ioMax) }
    end

    print "Total Ruby benchmark time:", t, "\n"
    puts "End Ruby benchmark"


    #####################For perl...
    #! /usr/bin/perl
    use Benchmark qw( timeit timestr );
    use Math::Trig; #for tan

    my $intMax = 1000000000; # 1B
    my $intMax = 10000000; # 1B
    my $doubleMin = 10000000.0; # 10B
    my $doubleMax = 11000000.0; # 11B
    my $longMin = 10000000; # 10B
    my $longMax = 11000000; # 11B
    my $trigMax = 100000.0; # 10M
    my $ioMax = 10000; # 1M

    sub intArithmetic($)
    {
    my ($intMax) = @_;

    my $i = 1;
    my $intResult = 1;
    while ($i < $intMax)
    {
    $intResult = $intResult - $i;
    $i++;
    $intResult = $intResult + $i;
    $i++;
    $intResult = $intResult * $i;
    $i++;
    $intResult = int $intResult / $i;
    $i++;
    }
    print " i:", $i, "\n";
    print " intResult:", $intResult, "\n";
    }


    sub doubleArithmetic($$)
    {
    my ($doubleMin, $doubleMax) = @_;

    my $i = $doubleMin;
    my $doubleResult = $doubleMin;
    while ($i < $doubleMax)
    {
    $doubleResult = $doubleResult - $i;
    $i = $i + 1.0;
    $doubleResult = $doubleResult + $i;
    $i = $i + 1.0;
    $doubleResult = $doubleResult * $i;
    $i = $i + 1.0;
    $doubleResult = $doubleResult / $i;
    $i = $i + 1.0;
    }
    print " i:", $i, "\n";
    print " doubleResult:", $doubleResult, "\n";
    }


    sub longArithmetic
    {
    my ($longMin, $longMax) = @_;

    my $i = $longMin;
    my $longResult = $longMin;
    while ($i < $longMax)
    {
    $longResult = $longResult - $i;
    $i = $i + 1;
    $longResult = $longResult + $i;
    $i = $i + 1;
    $longResult = $longResult * $i;
    $i = $i + 1;
    $longResult = $longResult / $i;
    $i = $i + 1;
    }
    print " i:", $i, "\n";
    print " longResult:", $longResult, "\n";
    }

    sub log10 { log($_[0])/log(10); }

    sub trig($)
    {
    my ($trigMax) = @_;
    my $i = 1.0;
    my $sine = 0.0;
    my $cosine = 0.0;
    my $tangent = 0.0;
    my $logarithm = 0.0;
    my $squareRoot = 0.0;

    while ($i < $trigMax)
    {
    $sine = sin($i);
    $cosine = cos($i);
    $tangent = tan($i);
    $logarithm = log10($i);
    $squareRoot = sqrt($i);
    $i = $i + 1.0;
    }
    print " i:", $i, "\n";
    print " sine:", $sine, "\n";
    print " cosine:", $cosine, "\n";
    print " tangent:", $tangent, "\n";
    print " logarithm:", $logarithm, "\n";
    print " squareRoot:", $squareRoot, "\n";
    }


    sub io($)
    {
    my ($ioMax) = @_;
    my $fileName = "TestPerl.txt";
    my $myString = "abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefgh\n";
    my $linesToWrite = $myString;
    for $i ( 1..$ioMax )
    {
    $linesToWrite .= $myString;
    }

    open(FILE, ">".$fileName);
    print FILE $linesToWrite;
    close(FILE);

    open(FILE, "<".$fileName);
    my @readLines = <FILE>;
    print "length:",$#readLines,"\n";
    close(FILE);
    }


    # Main program begins here

    print "Start Perl benchmark\n";



    my $total= timeit( 1, sub
    {
    my $t = timeit( 1, sub{intArithmetic($intMax); } );
    print "intArithmetic: ",timestr($t),"\n";
    $t = timeit( 1, sub{doubleArithmetic($doubleMin,$doubleMax); } );
    print "doubleArithmetic: ",timestr($t),"\n";
    $t = timeit( 1, sub{doubleArithmetic($longMin,$longMax); } );
    print "longArithmetic: ",timestr($t),"\n";
    $t = timeit( 1, sub{trig($trigMax); } );
    print "trig: ",timestr($t),"\n";
    $t = timeit( 1, sub{io($ioMax); } );
    print "io: ",timestr($t),"\n";
    }
    );

    print "total=",timestr($total),"\n";

    print "End Perl benchmark";
     
    GGarramuno, Jan 12, 2004
    #14
  15. On Monday 12 of January 2004 16:59, David Garamond wrote:
    > Emmanuel Touzery wrote:
    > > i have the feeling (unconfirmed) that perl is optimising it away since
    > > the result is unused or the operation repeated or something. i created a
    > > file with 1000000 lines repeating the addition and perl is very slow too
    > > then (and ruby too).

    >
    > do you mean you did:
    >
    > #!/usr/bin/{perl,ruby}
    > 1234567+123456;
    > 1234567+123456;
    > 1234567+123456;
    > 1234567+123456;
    > 1234567+123456;
    > ...
    >
    > ?
    >
    > then have you factored out compilation overhead? I would wild-guess that
    > Perl is slightly slower than Ruby, due to its complex syntaxes?


    i did try with a file as you said, but due to a slow computer i had to kill it
    before the end. when i first ran it, i saw perl was slow, which seemed to
    confirm this 'perl is caching the result' intuition, i didn't think about the
    syntax parsin overhead :O)

    now i tried on a faster computer:

    [emmanuel@papillon emmanuel]$ time perl test.rbpl
    10.63user 1.01system 0:35.49elapsed 32%CPU (0avgtext+0avgdata 0maxresident)k
    0inputs+0outputs (6628major+98402minor)pagefaults 0swaps
    [emmanuel@papillon emmanuel]$ time ruby test.rbpl
    test.rbpl:8127:in `+': Bignum can't be coerced into Fixnum (TypeError)
    from test.rbpl:8127
    Command exited with non-zero status 1
    26.86user 0.71system 0:28.19elapsed 97%CPU (0avgtext+0avgdata 0maxresident)k
    0inputs+0outputs (254major+51518minor)pagefaults 0swaps

    i'm not really sure why ruby is choking on line 8127, all lines are identical
    and read '1073741823+1073741824;'
    but anyway it shows that in any case ruby is still much slower than perl, so
    nevermind what i said. as far as i'm concerned, it's not sure at all that
    perl is saving the calculation. my initial impression was simply caused by
    the huge difference between ruby and perl.

    emmanuel

    PS: if someone is interested in this ruby error, the file is too big to send,
    but is so that:
    [emmanuel@papillon emmanuel]$ uniq test.rbpl
    1073741823+1073741824;

    [emmanuel@papillon emmanuel]$ wc -l test.rbpl
    1000001 test.rbpl

    PPS: great trick with NArray.. :O)
     
    Emmanuel Touzery, Jan 12, 2004
    #15
  16. David Garamond

    Neil Spring Guest

    On Tue, Jan 13, 2004 at 04:47:59AM +0900, Emmanuel Touzery wrote:
    > got around bzipping2 it. it's attached, if someone cares. bunzip2 it,
    > run with
    > ruby and you'll get
    > test.rbpl:8127:in `+': Bignum can't be coerced into Fixnum (TypeError)
    > from test.rbpl:8127


    > which seems to be an error.


    > (ruby 1.8.0 (2003-08-04) [i586-linux-gnu])


    and with --enable-pthread

    jimbo:~> ruby1.8 ./test1.rbpl
    /test1.rbpl:6250: stack level too deep (SystemStackError)
    33.665u 1.132s 0:35.33 98.4% 0+0k 0+0io 269pf+0w

    jimbo:~> ruby1.8 --version
    ruby 1.8.1 (2003-12-27) [i386-linux]

    jimbo:~> ruby1.8 -r rbconfig -e "puts Config::CONFIG['configure_args']"
    '--enable-frame-address' '--target=i386-linux' '--program-suffix=1.8' '--prefix=/usr' '--datadir=/usr/share' '--mandir=/usr/share/man' '--sysconfdir=/etc' '--localstatedir=/var' '--with-sitedir=/usr/local/lib/site_ruby' '--with-default-kcode=none' '--with-dbm-type=gdbm_compat' '--with-tklib=tk8.4' '--with-tcllib=tcl8.4' '--with-tcl-include=/usr/include/tcl8.4' '--enable-pthread' '--enable-shared' '--enable-ipv6' '--with-lookup-order-hack=INET' 'CFLAGS=-Wall -g -O2' 'target_alias=i386-linux'

    debian 1.8.1-2, though I verified the effect of
    --enable-pthread with current cvs as well.

    -neil
     
    Neil Spring, Jan 12, 2004
    #16
  17. wrote:

    > if there is someway you can organized your problem into arrays (eg. collecting
    > the item to sum into one), narray might be the way to go, it offer blindingly
    > fast numerical operations:
    >
    > ~ > time ruby -r narray -e 'NArray.int(1000000)[true] = 1073741823+1073741824'


    But isn't this only performing the addition once?
     
    Joel VanderWerf, Jan 12, 2004
    #17
  18. David Garamond

    Dave Brown Guest

    In article <4002C471.1070507@zara.6.isreserved.com>,
    David Garamond <lists@zara.6.isreserved.com> wrote:
    : Emmanuel Touzery wrote:
    : > i have the feeling (unconfirmed) that perl is optimising it away since
    : > the result is unused or the operation repeated or something. i created a
    : > file with 1000000 lines repeating the addition and perl is very slow too
    : > then (and ruby too).
    :
    : do you mean you did:
    :
    : #!/usr/bin/{perl,ruby}
    : 1234567+123456;
    : 1234567+123456;
    : 1234567+123456;
    : 1234567+123456;
    : 1234567+123456;
    : ..
    :
    : ?
    :
    : then have you factored out compilation overhead? I would wild-guess that
    : Perl is slightly slower than Ruby, due to its complex syntaxes?

    Nope.

    :) [~] head -2 foo
    1073741823+1073741824;
    1073741823+1073741824;
    :) [~] wc -l foo
    100000 foo
    :) [~] time perl foo
    perl foo 1.37s user 0.06s system 99% cpu 1.431 total
    :) [~] time python foo
    python foo 2.55s user 0.22s system 100% cpu 2.769 total
    :) [~] time ruby foo
    ruby foo 3.03s user 0.10s system 98% cpu 3.165 total

    Still, that's not a difference which I'm overly worried about.

    --Dave
     
    Dave Brown, Jan 13, 2004
    #18
  19. David Garamond wrote:

    > 2. Doing arbitrary integer math is already very convenient in Ruby
    > because of its automatic conversion. But Ruby still doesn't do
    > seamless conversion to arbitrary floating point numbers:
    >
    > $ irb
    > irb(main):001:0> 0.00000000000000001
    > => 1.0e-17
    > irb(main):002:0> 0.000000000000000001
    > => 0.0
    >
    > Any chance Ruby will do this in the future? Or perhaps in the nearer
    > future, include an arbitrary floating number package in its
    > distribution (is there any? GMP is GPL so it potentially a problem
    > license-wise).
    >

    btw, just saw a mention of this today: isn't maybe ext/bigdecimal what
    you want? shipped with ruby-1.8.0.

    emmanuel
     
    Emmanuel Touzery, Jan 13, 2004
    #19
  20. Emmanuel Touzery wrote:
    >> Any chance Ruby will do this in the future? Or perhaps in the nearer
    >> future, include an arbitrary floating number package in its
    >> distribution (is there any? GMP is GPL so it potentially a problem
    >> license-wise).
    >>

    > btw, just saw a mention of this today: isn't maybe ext/bigdecimal what
    > you want? shipped with ruby-1.8.0.


    Yes, exactly what I wanted. Thanks.

    --
    dave
     
    David Garamond, Jan 13, 2004
    #20
    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. Honestmath
    Replies:
    5
    Views:
    589
    Honestmath
    Dec 13, 2004
  2. Luna Moon
    Replies:
    9
    Views:
    656
    Wade Ward
    Sep 25, 2007
  3. Luna Moon
    Replies:
    9
    Views:
    498
    Wade Ward
    Sep 25, 2007
  4. Alasdair
    Replies:
    15
    Views:
    792
    Steven D'Aprano
    Mar 9, 2008
  5. Stanimir Stamenkov
    Replies:
    4
    Views:
    2,649
    Stanimir Stamenkov
    Jul 18, 2008
Loading...

Share This Page