Friday, August 24, 2007

Erlang: Concurrency and Distribution (Part 2)

One of the main strengths for Erlang is support for concurrency and distribution. It has a small set of primitives to create processes and communicate between them. Erlang processes are not operating system processes or threads, but they are lightweight threads similar to Java's "green threads".

Erlang is designed to be run in a distributed multi-node environment. Every computation in Erlang is performed within a process. Processes have no shared memory and communicate by asynchronous message passing. This is the philosophy of Erlang, the Concurrency Oriented Programming (COP). You have to think of your design from this prospective. Your application consists of a set of processes may be distributed on different machines.

Here is a simple application to illustrate the feautres I was talking about. A process sends a message to another process using the send construct: Pid ! Message. Even if the Pid doesn’t exist, the send will succeed. A process can block to receive a message by using the receive construct. The receive construct may also take an optional timeout value in millseconds, after which the “after” clause of the receive construct is executed.


-module(IPCExample).

-export([main/0, thread/0]).

main() ->

Pid = spawn(receive1, thread, []),

io:fwrite("Spawned new process _w_n", [Pid]),

Pid ! hello.

thread() ->

io:fwrite("This is a thread._n", []),

process_messages().

process_messages() ->

receive

hello ->

io:fwrite("Received hello_n"),

process_messages()

after 2000 ->

io:fwrite("Timeout._n")

end.


Process IDs do not have to refer processes running on the same machine as the processes can be distributed an remote machines. So you can spawn a process using the node name and use the returned process ID to send messages just as if it were a process on the local machine.


Pid = spawn(remote_node,process1, thread, []) Pid ! a_message
Pid ! a_message


Erlang handles the creation of the processes very efficiently. Here is a simple graph comparing Java, C#, Erlang comparing the time taken to create processes and asynchronous message passing.


This figure compares the time of creation of processes in Erlang versus Java and C#. We observe that the time taken to create an Erlang process is a constant 1 micro second up to 2,500 processes; and then it increases to about 3 micro second for up to 30,000 processes. As for Java and C# a small number of processes takes about 300 micro second to create a process. Creating more than two thousand processes is impossible.
This figure compares the time of message passing between different processes in Erlang versus Java and C#. The time to send a simple message between two concurrent processes running on the same machine as a function of the total number of processes. We see that for up to 30,000 processes the time to send a message between two Erlang processes is about 0.8 micro second. For C# it takes about 50 micro second. per message, up to the maximum number of processes (which was about 1800 processes). Java was even worse, for up to 100 process it took about 50 micro second per message thereafter it increased rapidly to 10ms per message when there were about 1000 Java processes.

It is quite clear that Java and C# can't compete with Erlang in this features. We have to realize that the world is going towards parallel processing even we don't accept Erlang as a language I think it will take place in the next decade.

To be continued ...

4 comments:

Patrick said...

Scala has an Actor library that does better than Java, though not as well as Erlang--but then Erlang has a VM written with this sort of processing in mind. See http://lamp.epfl.ch/~phaller/doc/haller07actorsunify.pdf and http://lamp.epfl.ch/~phaller/doc/haller06jmlc.pdf. They show some benchmarks. Regards Patrick

NickG said...

It's not clear that your observations are based on a valid comparison. Erlang processes are just small internal constructs (a few hundred bytes each) all running within a single VM process. If you compare this with 'real' process creation, you would expect large disparities, particularly on Windows. It would be useful if you could publish your methodology.

chandana said...

You need to publish your java source code also. Then we can decide what is the better. I believe erlang process creation time is more lower than java Thread creation time. But we should design our program according to the language. For example in java and C#, we can use thread pool or executor service instead of creation many many process or threads.

Anonymous said...

Just tested on my notebook:
Creation of 2000 AppDomains took 0.743 milliseconds pro AppDomain.

Please, recheck your calculation