Sunday, September 26, 2010

C, Java, Erlang, Prolog, Haskell: naive banchmark

Here comes a naive benchmark for C, Java, Erlang, Prolog and Haskell. The benchmark is to compute Pythagorean triples. The triple consists of three positive integers a, b, and c, such that a*a + b*b = c*c and additionally a+b+c<=n, where n=500.

Haskell:

f :: Int -> [ (Int, Int, Int) ]
f n = [ (x, y, z) | 
    x <- [ 1 .. n ],
    y <- [ 1 .. n ],
    z <- [ 1 .. n ],
    x + y + z <= n,
    (x * x) + (y * y) == (z * z) ]
Prolog:
pytriangle(N,A,B,C):-
    between(1,N,A),
    between(1,N,B),
    between(1,N,C),
    A + B + C =< N ,
    A*A + B*B =:= C*C.
Erlang:
-module(test).
-export([pythag/1]).

pythag(N) ->
    [ {A,B,C} ||
        A <- lists:seq(1,N),
        B <- lists:seq(1,N),
        C <- lists:seq(1,N),
        A+B+C =< N,
        A*A+B*B =:= C*C
    ].
C:
int main(int argc,char *argv[]){
    int a,b,c,n;
    n=atoi(argv[1]);

    for (a=1; a<=n; a++) {
        for (b=1; b<=n; b++) {
            for (c=1; c<=n; c++) {
                if ((a+b+c <= n) && (a*a + b*b == c*c)){
                    printf("%d,%d,%d;",a,b,c);
                }
            }
        }
    }
    return 0;
}
Java:
public class triangles
{
    public static void main(String [] args)
    {
        int a,b,c,n;

        n=Integer.parseInt(args[0]);
        for (a=1; a<=n; a++) {
            for (b=1; b<=n; b++) {
                for (c=1; c<=n; c++) {
                    if ((a+b+c <= n) && (a*a + b*b == c*c)){
                        System.out.printf("%d,%d,%d;",a,b,c);
                    }
                }
            }
        }
    }
}

Here comes the results (in seconds).

Haskell (GHCi, version 6.12.1): 380
Haskell compiled (GHCi, version 6.12.1): 32
Prolog (SWI Prolog 5.7.4): 197.2
Erlang (R13B03): 59.5
Erlang HiPE (High Performance Erlang), native: 13.2
C (gcc 4.4.3): 0.8
Java (IcedTea6 1.8.1): 2.2 (with output redirected to /dev/null: 1.3)

The winner was obvious from the begining. But it's quite interesting how the declarative languages perform... hmmm. Kudos to Erlang.

By the way, have you noticed that the code is far better readable with the declarative approach?

Sunday, September 5, 2010

Command line might: useful aliases; BASH tips

I'm a command-line-guy I guess. I use a terminal quite often (mostly with BASH), either for file management, or while working on my projects, just to launch proper application, and optionally to make it read some contents from a given file.

I found myself using quite often two particular functions:
  1. searching for a file which name contains a keyword, and
  2. figuring out what files I recently modified in the current directory.
These two functions can be easily written down as:

ls -l | grep -i some_keyword
ls -lt | head

Right, but since I use them quite often and being rather lazy I wouldn't want to type these every time... So here come aliases.
You can define an alias for a command you often type and use it instead.  So I decided to define two aliases: lsg and lst for searching for a file name containing a keyword and displaying the recently modified files respectively.

So if you type at your command prompt:

alias lsg='ls -l | grep -i'
alias lst='ls -lt | head'

From now one you can use lsg and lst freely.

If you want to make the change permanent you could add the above lines to your ~/.bashrc file, so the aliases would be accessible any time you log in.

Oh one more thing... how to use it.
If I want to find out what files I modified recently in the current directory I just type:

$ lst

and it gives me a list of recntly modified files. If I'm looking for a file which name contains a keyword "book" I issue:

$ lsg book

And I get a list of files which names contain "book" (case insensitive). It's quite useful - at least for me.

PS. Dont forget about: cd -
It will bring you up to the directory you were previously in.