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.

  1. 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 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

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.

  1. 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.

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

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

···

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.

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 :: Solar-Terrestrial Physics Data | NCEI
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’
===============================================================================

David Garamond wrote:

  1. 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

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

[...]

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).

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

$ 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.

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).

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

Guy Decoux

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

In article 4002BDA5.7080906@wanadoo.fr,

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

···

Emmanuel Touzery emmanuel.touzery@wanadoo.fr wrote:


mike@stok.co.uk | The “`Stok’ disclaimers” apply.
http://www.stok.co.uk/~mike/ | GPG PGP Key 1024D/059913DA
mike@exegenix.com | Fingerprint 0570 71CD 6790 7C28 3D60
http://www.exegenix.com/ | 75D2 9EC4 C1C0 0599 13DA

“Daniel Carrera” dcarrera@math.umd.edu schrieb im Newsbeitrag
news:20040112152151.GA846@math.umd.edu…

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.

  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.

  1. 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

···

On Tue, Jan 13, 2004 at 12:09:53AM +0900, David Garamond wrote:
Math Dept. UMD | inconvenienced.

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

Thanks,

···

Ara.T.Howard@noaa.gov 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?


dave

But isn’t this only performing the addition once?

···

Ara.T.Howard@noaa.gov 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’

What abouts Rubys design would make integer arithmetic slower than integer
arithmetic in Perl?

···


Charlie

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

ts wrote:

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).

just use a faster cpu

reminds me of Perl’s very powerful pragmas:

use less time;
use more cpu;

···


dave

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”;

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)

···

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?

class Fixnum
def +(other)
self.to_s + other.to_s
end
end

puts 1 + 2 #=> “12”

Ruby has to do full OO method dispatch for basic arithmetic operators.

Cheers

Dave

···

On Jan 12, 2004, at 15:43, Charles Mills wrote:

What abouts Rubys design would make integer arithmetic slower than
integer
arithmetic in Perl?