gen_tcp and message handling

Joe Armstrong (AL/EAB) joe.armstrong@REDACTED
Mon Jan 10 10:32:27 CET 2005

> > It is very easy, but slower !

 You've said the word that sets me off :-)
  But who cares about speed?

   Speed is only relative, it's either "fast enough" or not -
so write your code as beautifully as possible - and measure - if it's not
fast enough then measure and then optimise.

    One day you might have to maintain your code so it had better be beautiful.


When we started Erlang there was a lot of talk about "the 5'th generation" - the
Japanese has scared shit out of the Janks by starting a program to make a "mega LIPS" Prolog
machine - with this they would "crush the yanks" in the software world.

The mega-LISP machine would be able to do anything - natural language translation,
play chess, you name it.

The mega-lisp machine would be huge - dozens (maybe hundreds) of processors.

The first (Prolog based) Erlang interpreter ran at a few hundred ERPS -
but this was fast enough to sell the idea of using Erlang.

At the time we calculated we would need 80K ERPS to make a product - this was why we
developed the JAM (we were wrong we need 240K ERPS)

Today I've stopped measuring ERPS - we passed 1 Meg years ago (The laptop I'm typing this on runs in excess of 15MERPS).

I said many years ago (in about 1980) something like

"We should concentrate on making our software as beautiful and correct as possible -
then it's either fast enough or it's not. If it's not fast enough we WAIT - then
one day (due to processor speed ups it will be fast enough) - our software will then
be less buggy and easier to modify and maintain than all the oppositions SW - and
we win"

Now a lot of software (TCP/IP stacks, protocol implementations) are here to stay -
so the message is still true.

So please write your stacks as inefficiently as possible - and WAIT.
The funny thing about writing code as inefficiently as possible is that the resulting
code is often faster than code written with efficiency in mind - this is because
beautiful code should be clear, concise, as-efficient as possible (subject to being
beautiful) use the best algorithms possible and be clearly layered and documented.
In other words - a minor work of art.

The Erlang model of the world is "everything is a process" - so things that are not processes
should be faked up to look like processes and to respond to messages/links just as if
they were processes - so yes please do make TCP streams look and feel like processes and
ONLY make it more efficient if you absolutely have to.

I do this all the time. So I abstract protocols drivers as processes, so I can write

	Http = spawn(fun() -> http_driver("", 80),
	Http ! {get, "/foo/bar"},
	    {Http, {text, Bin}} ->
		  Browser ! {render, Bin}


This is called "conceptual integrity"



> I trust you know better than me, but could you be a bit more 
> elaborate 
> as to why it is slower? I would guess it would only be marginally 
> slower to do
>   Process -- signal --> registered process --> gen_tcp:send -> Socket
> than to have Socket be a process itself that can be 
> signalled, and have
>   Process -- signal --> Socket process
> but maybe I'm missing something. Maybe gen_tcp:send() is actually a 
> signal to a process already. Then I would agree with you that 
> it would 
> actually make a difference. I have to read the source ;)
> /Fredrik

More information about the erlang-questions mailing list