Saturday, September 29, 2007

Erlang/Java Performance in Concurrency

I've been learning Erlang for 1 week now and i discover its a nice language for programming. This language is definitely different from C, C++ and Java.

In this post, i shall boldly compare the difference in runtimes for Erlang and Java w.r.t. concurrency.

In Erlang, I created a file ring.erl which contains the following code


-module(ring).
-export([start/2, for/3, loop/0]).

-ifndef(debug).
-define(TRACE(X), io:format("~p:~p ~p~n", [?MODULE, ?FILE, X])).
-else.
-define(TRACE(X), void).
-endif.

for(N, N, F) -> F();
for(I, N, F) -> F(),for(I+1, N,F).

%
% Create N processes and send a message M times
% to each process. Therefore, we should generate N * M
% messages.
%

loop() ->
receive
{msg, Pid} -> Pid, loop()
after 5000 ->
done
end.

start(N, M) ->
statistics(runtime),
statistics(wall_clock),
ring:for(1, N, fun() -> Pid = spawn(ring, loop, []), ring:for(1, M, fun() -> Pid ! {msg, Pid} end) end),
{_, Time1} = statistics(runtime),
{_, Time2} = statistics(wall_clock),
io:format("Runtime:~p, Walltime:~p~n", [Time1, Time2]).


In Java, I used Netbeans 5.5.1 (JDK 1.5.0_12) to develop the following simple multi-threaded Java code:


package simplemultithread;

public class Main {

/** Creates a new instance of Main */
public Main() {
}

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
long startTime = System.currentTimeMillis();
if ( args.length != 2 ) {
System.err.println("usage: java Main <Number of threads> <Number of msg to send to each thread>");
System.exit(-1);
}
int numOfThreads = Integer.parseInt(args[0]);
final int numOfMsgsPerThread = Integer.parseInt(args[1]);
Thread threads[] = new Thread[numOfThreads];

for( int i = 0; i < numOfThreads; i++ ) {
threads[i] = new Thread() {
private int msgsToProcess = numOfMsgsPerThread;
public void run() {
for( int i = 0, j = 0; i < msgsToProcess; i++ ) {
// do something simple
j++;
}
}
};
try { threads[i].join();} catch (InterruptedException ie) {}
}
for( int i = 0; i < numOfThreads; i++ ) {
threads[i].start();
}
long endTime = System.currentTimeMillis();
System.out.println("Total time:" + (endTime - startTime)/1000.00 + "seconds");
}

}


And the performance difference is quite remarkable after comparing the runtimes of both programs which perform almost the same thing i.e. start N processes/threads and each process executes its action M-times.

In my tests, i used a Compaq notebook Intel-M 2.4 Ghz with 512 MB RAM running SUSE Linux 9.3 Professional Operating System.

The figure on the left is the runtime, in milliseconds, of the Erlang code above and that on the right is that of the Java code. From the figures, you can see that Erlang runs better than Java in order of approximately 2-3 times!

How does Erlang do it? The best way to understand it is to see this article.


Wednesday, September 26, 2007

Understand your implementation by "tracing" the execution

In my previous post, i used Erlang to implement 2 simple algorithms when run, produced the desired results which i am pleased. But, upon reflection i found that i need to better my understanding of how Erlang executes the function i knew i needed to trace it.

Therefore, how do you add "debug/trace" feature into your own implementations ?

What i did is:

1/ Create a macro named "TRACE"
2/ Compiled the code using the "c"-command with an extra argument
3/ Ran the compiled code to view it, and voila! its done.

Below is an illustration of how i did it:


%
% Create a Erlang macro and include it in your *.erl file
%
-ifdef(debug).
-define(TRACE(X), io:format("TRACE ~p:~p ~p~n", [?MODULE, ?LINE, X])).
-else.
-define(TRACE(X), void).
-endif.
...
...
...
%
% N-th Permutation
% Note: the code in "bold" is an expansion of the newly created macro "TRACE"
%
perms([]) -> [[]];
perms(L) -> ?TRACE(L), [[H|T] || H <- L, T <- perms(L--[H])]. ... ...


Now, once you have done this naturally you would save the file and next you start up the Erlang shell and compile the file as illustrated in the screenshot below, afterwhich you run it!

Friday, September 21, 2007

Implementing Algorithms (Part 1)

I just started learning this language which belongs to a class of languages known as Functional Language.

For starters, I am going to demonstrate some simple stuff.

1/ Calculate Factorial


%
% Algorithm to calculate the Nth Factorial
%
-module(fac).
-export([factorial/1]).

factorial(0) -> 1;
factorial(1) -> 1;
factorial(N) when N > 0 -> N * factorial(N-1).

2/ Calculate N-th Fibonacci Sequence


%
% Algorithm to calculate the sum of Nth Fibonacci Sequence
%
-module(fib).
-export([fibonacci/1]).

fibonacci(0) -> 0;
fibonacci(1) -> 1;
fibonacci(N) when N > 1 -> fibonacci(N-1) + fibonacci(N-2).

In order to run the above scripts, do the following

a) Create a file call fac.erl or fib.erl (Note: name of file must be the same as the string given in the "-module")
b) Copy and paste the respective code into the respective file
c) Start up the Erlang Shell and type the following (Note the period character '.'):
c.1) c(fib).
c.2) c(fac).
If your compilation was successful, you should have the following screen

Wednesday, September 19, 2007

What is Erlang and what is its role going to be ?

I borrowed the following quote from the book Programming Erlang

For years we have relied on processors getting faster and faster. That trend is ending. Instead, we now have multicore processors - 2, 4 or more processors running in parallel. The problem is, unless your program can execute in parallel, it will use only one of these cores at a time.

The Erlang programming language lets you build highly parallel, distributed, fault-tolerant systems - systems that can exploit these new architectures. It has been used commercially for many years to create massive fault tolerant and highly reliable systems.

Erlang programs run seamlessly on multicore computers with no extra code on your part. Erlang combines ideas from the world of functional programming with techniques for building fault-tolerant systems. The result is a powerful language that makes it much easier to build the massively parallel networked applications of the future.
Therefore, in the coming blogs i am going to write stuff about Erlang and programming in it, in general.

For a brief introduction to the language features, follow this article.