C, Perl, Java, Python, Ruby, PHP ¿quién es más veloz?

Esta mañana estaba algo aburrida y se me ocurrió hacer un experimento: comparar la velocidad a la que se ejecuta un mismo algoritmo en diversos lenguajes de programación. Para ello, hice un pequeño algoritmo que imprime parte de la serie de Fibonacci, en los siguientes lenguajes:

En C. Archivo: foo.c

#include <stdio.h>

foo(int a, int b) {
    if (a + b > 0) printf("%i ", a + b);
    if (a + b < 100000000) foo(b, a + b);
}

main() {
    foo(-1, 1);
    printf("n");
}

En Java. Archivo: Foo.java

public class Foo {

    public static void main(String[] args) {
        Foo f = new Foo();
        f.foo(-1, 1);
        System.out.print("n");
    }

    public void foo(int a, int b) {
        if (a + b > 0) { System.out.print(a + b + " "); }
        if (a + b < 100000000) { this.foo(b, a + b); }
    }

}

En Perl. Archivo: foo.pl

#!/usr/bin/perl

sub foo {
    ($a, $b) = @_;
    if($a + $b > 0) { print $a + $b . " "; }
    if($a + $b < 100000000) { foo($b, $a + $b); }
}

foo(-1, 1);
print "n";

En Python. Archivo: foo.py

#!/usr/bin/python
from sys import stdout


def foo(a, b):
    if a + b > 0:
        stdout.write("%i " % (a + b))
    if a + b < 100000000:
        foo(b, a + b)


foo(-1, 1)
print ""

En PHP. Archivo: foo.php

#!/usr/bin/php
< ?php

function foo($a, $b) {
    if($a + $b > 0) print $a + $b . " ";
    if($a + $b < 100000000) foo($b, $a + $b);
}

foo(-1, 1);
print chr(10);

?>

[nuevo] En Ruby. Archivo: foo.rb

#!/usr/bin/ruby


def foo(a, b)
    if (a + b) > 0
        print a + b , " "
    end

    if (a + b) < 100000000
        foo(b, a + b)
    end
end

foo(-1, 1)
puts " "

Exceptuando los archivos en C y Java que deberán ser compilados (ver más adelante), al resto de los archivos les asigné permisos de ejecución para que sea más cómodo correrlos:

chmod +x foo.php foo.py foo.pl foo.rb

Y a continuación, me dediqué primero, a comparar la velocidad de compilación entre Java y C y obtuve estos resultados:

Tiempo de compilación en C:

time gcc foo.c -o fooc

<b>real 0m1.970s</b>
user    0m0.028s
sys 0m0.048s

Tiempo de compilación en Java:

time javac Foo.java

<b>real 0m3.769s</b>
user    0m0.816s
sys 0m0.100s

Se podría decir que la compilación en C, tardó (más o menos) la mitad del tiempo que la compilación en Java.

Finalmente ejecuté cada uno de los micro-programas, dos veces cada uno: la primera, para que se cachearan y la segunda, para comparar la diferencia en la velocidad de ejecución y ésto, fue lo que obtuve:

Tiempo de ejecución en C: 0.002 segundos

[email protected]:~$ time ./fooc
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
6765 10946 17711 28657 46368 75025 121393 196418 317811 
514229 832040 1346269 2178309 3524578 5702887 9227465 
14930352 24157817 39088169 63245986 102334155 

real    0m0.002s
user    0m0.000s
sys 0m0.000s

Tiempo de ejecución en Java: 0.143 segundos

[email protected]:~$ time java Foo
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
6765 10946 17711 28657 46368 75025 121393 196418 317811 
514229 832040 1346269 2178309 3524578 5702887 9227465 
14930352 24157817 39088169 63245986 102334155 

real    0m0.143s
user    0m0.112s
sys 0m0.028s

Tiempo de ejecución en Perl: 0.003 segundos

eugen[email protected]:~$ time ./foo.pl
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
6765 10946 17711 28657 46368 75025 121393 196418 317811 
514229 832040 1346269 2178309 3524578 5702887 9227465 
14930352 24157817 39088169 63245986 102334155 

real    0m0.003s
user    0m0.000s
sys 0m0.000s

Tiempo de ejecución en Python: 0.038 segundos

[email protected]:~$ time ./foo.py
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
6765 10946 17711 28657 46368 75025 121393 196418 317811 
514229 832040 1346269 2178309 3524578 5702887 9227465 
14930352 24157817 39088169 63245986 102334155 

real    0m0.038s
user    0m0.024s
sys 0m0.012s

Tiempo de ejecución en PHP: 0.027 segundos

[email protected]:~$ time ./foo.php
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
6765 10946 17711 28657 46368 75025 121393 196418 317811 
514229 832040 1346269 2178309 3524578 5702887 9227465 
14930352 24157817 39088169 63245986 102334155 

real    0m0.027s
user    0m0.020s
sys 0m0.004s

Tiempo de ejecución en Ruby: 0.009 segundos

[email protected]:~$ time ./foo.rb
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
6765 10946 17711 28657 46368 75025 121393 196418 317811 
514229 832040 1346269 2178309 3524578 5702887 9227465 
14930352 24157817 39088169 63245986 102334155  

real    0m0.009s
user    0m0.004s
sys 0m0.004s

Si se tratara de una carrera de autos 😀 la tabla de posiciones sería como la siguiente:

================================================
     <b>Turismo Compilación</b>
================================================
Primer puesto:   C
Segundo puesto:  Java

================================================
     <b>Turismo Ejecución</b>
================================================

PUESTO       PILOTO        TIEMPO (en segundos)
------------------------------------------------
1º           C             0.002
2º           Perl          0.003
3º           Ruby          0.009 ¡Nuevo competidor! :)

4º           PHP           0.027
5º           Python        0.038

6º           Java          0.143

Es decir que PHP demoró 13.5 veces más que C; Python, 12.6 veces más que Perl y Java… mejor no lo comparo con ninguno 😀