From: GGarramuno@... (GGarramuno) Date: 2004-01-13T04:36:40+09:00 Subject: Re: faster integer arithmetics & arbitrary precision floating number David Garamond 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 = ; 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";