Ruby Performance Revisited 6
For this post I used a code snippet I found from a fellow programmer, Antonio Cangiano, that ran the tests again myself because I couldnt believe my eyes of the benchmarks run by that user.
Fibonacci Language Shootout:
Languages
- Ruby 1.8.6
- Ruby 1.9.0 (Development Release)
- Python 2.5.1
- Perl 5.8.8
- Java 1.5.0
- C++
Below are the languages and the times that each took to run the code. The code for each languages is below near the end of the post.
Ruby 1.8.6
real 0m44.965sPython 2.5.1
real 0m28.283sRuby 1.9.0
real 0m11.352sC++
real 0m0.765sJava
real 0m0.638sPerl
real 0m70.383sI will be comparing this performance of Ruby and Python to a program written in C. Below is the code used in these examples. Feel free to comment. I am running further tests using statistical analysis to make the output exhibit less of a standard deviation.
Python
def fib(n):
if n == 0 or n == 1:
return n
else:
return fib(n-1) + fib(n-2)
for i in range(36):
fib(i)Ruby
def fib(n)
if n == 0 || n == 1
n
else
fib(n-1) + fib(n-2)
end
end
36.times do |i|
fib(i)
endBelow is the source code for the fib sequence written in C++. Paul Solt recommended that the tests be performed without and writing to STDOUT due to the variability and slow down caused by writing to STDOUT. Since this was done for the C++ code it was done for the rest of the examples above. For the record there was no increase in speed when the output was removed.
C++
#include <stdio.h>
#include <iostream>
int fib( int n ) {
if( n== 0 || n == 1 ) {
return n;
} else {
return fib( n -1) + fib( n-2);
}
}
int main() {
for( int i = 0; i < 36; i++ ) {
fib(i);
}
return 0;
}Java
public class fibtest {
public static void main(String[] args) {
for(int i=0; i<36; i++) {
fib(i);
}
}
public static int fib(int n) {
if( n == 0 || n == 1 )
return n;
} else {
return fib(n-1) + fib(n-2);
}
}
}Perl
sub fib { return $[0] if $[0] == 0 || $_[0] == 1; fib($[0]-1) + fib($[0]-2); }
for($i=0;$i<36;$i++) { fib($i); }I would like to extend my thanks to the developers that submitted, or contributed to this post in anyway.
Java & Perl Code - Jason Koppe
Trackbacks
Use the following link to trackback from your own site:
http://www.sysadminschronicles.com/trackbacks?article_id=ruby-performance-revisited&day=20&month=02&year=2008
Awesome stuff!
I think the results are largely dependent on the type of code you run. In order to get a better sense of the actually performance benefits you should try running your performance tests with different types of functions/algorithms.
The Fibonacci algorithm you used is recursive and there are different improvements that the compiler/interpreters can do to make it faster, but they may not all do it. This is probably why there’s a huge speed difference.
Also, the reason you didn’t see any performance increase when you removed the print statement is because the time to do the calculation is much greater than the time needed for output.
Good comments… The increase in speed for the recursive function calls is very interesting – to have such a substantial decrease in time from 1.8.4 to 1.9 is cool. What modifications to an interpreter could decrease the running time that much? I wonder about the (dis)advantages of external memoization and if it’s practiced in any compiled or interpreted language runtimes.
Ron, how did you measure the running times for these?
I’m interested to see how perl compares with your time measurement – and after that, PowerShell :) I’m also interested to see the running time comparisons for all of these scripting languages (not really too concerned with the compiled languages) for non-recursive algorithms.
In my basic tests, Sun’s Java jdk-1.5.0_14-fcs completed in 0.894 seconds and perl-5.8.8-30.fc8 completed in 112.039 seconds; Ron can you add this code to your post?
Java(0.638s):
public class fibtest { public static void main(String[] args){ for(int i=0; i<36; i++) fib(i); } public static int fib(int n) { if( n == 0 || n == 1 ) return n; else return fib(n-1) + fib(n-2); } }
Perl(70.383s):
sub fib { return $[0] if $[0] == 0 || $_[0] == 1; fib($[0]-1) + fib($[0]-2); }
for($i=0;$i<36;$i++) { fib($i); }
Oh, heres how i tested the runtimes
[root@localhost scriptingtest]# java ms && java fibtest && java ms
1203579932308
1203579932946
[root@localhost scriptingtest]# java runtime
1203579932308
1203579932946
0.638s
[root@localhost scriptingtest]# java ms && perl fibtest.pl && java ms
1203579954835
1203580025218
[root@localhost scriptingtest]# java runtime
1203579954835
1203580025218
70.383s
[root@localhost scriptingtest]# java ms && echo “” && java ms
1203580373737
1203580373896
[root@localhost scriptingtest]# java runtime
1203580373737
1203580373896
0.159s
[root@localhost scriptingtest]# cat runtime.java
import java.util.Scanner; public class runtime { public static void main(String[] args){ Scanner i = new Scanner(System.in); long s = i.nextLong(); long e = i.nextLong(); System.out.println(((e-s)/1000.0)+”s”); } }
Jason, That was very interesting to see the results of Java and Perl matched up, I will add the code and performance tests to the post.
Paul, Exactly, I would like to runs some more in-depth tests this weekend.
You should run the java/perl code in the same test environment for a more accurate comparison.