World's "Fastest" Small Web Server Released, Based On LISP
Cougem writes "John Fremlin has released what he believes to be the worlds fastest webserver for small dynamic content, teepeedee2. It is written entirely in LISP, the world's second oldest high-level programming language. He gave a talk at the Tokyo Linux Users Group last year, with benchmarks, which he says demonstrate that 'functional programming languages can beat C.' Imagine a small alternative to Ruby on rails, supporting the development of any web application, but much faster."
Sorry its the third oldest this is the oldest.
Designed by Konrad Zuse who also invented the first program-controlled Turing-complete computer. Fortran is the second oldest programming language.
It can be, but any decent production implementation is compiled to native machine codes -- it just includes compiler (and usually pretty fancy optimizing one!) built into the image and always available.
Try running, say, SBCL one day before spreading misunderstandings...
Paul B.
Parent post is inflammatory but not troll. He has a point, this implementation is a minimal test case built in order to prove a point. A skilled C programmer could implement the same test case that would perform better than the LISP one, if the task was worthy.
C is not how a modern processor thinks, with super-scalar instruction issue, cache and pre-fetch memory controls, and speculative branch prediction. In the end, even the C community splits into camps that let the optimizer do everything, versus embed some hand-written assembly or equivalent "machine intrinsics" routines in the middle of their normal C code. In both cases, non-trivial amounts of profiling and reverse-engineering are often needed to coax an appropriate machine code stream into existence, and this machine code is decidedly not how the developers usually think.
The choice of language is not so significant really. You can find Lisp dialects that efficiently use native machine types and have little runtime cost due to having weak type systems (just like C) where casting is easy and the responsibility for crazy results lives with the programmer and the limited ability of the compiler to check some static cases. These dialects will run imperative code quite well, e.g. if you transliterated typical C procedures into equivalent Lisp procedures, you'd get similar performance. Ironically, these systems aren't as fast when you write very high-level or functional Lisp, because those sorts of programs rely on a more elaborate optimization and runtime support layer, e.g. to optimize away recursive function call overheads or frequent allocation and destruction of temporary data like lists. This kind of code also doesn't work well in C, so the programmer has to perform these optimizations at the source level, by writing loops instead of recursion and making use of stack variables and static data structures instead of making many malloc/free calls in inner-loops, etc.
The main difference is the presumed runtime system for the language, the compilation goals, and the core language libraries. This includes things like whether you have garbage collection or explicit memory management, how you compile (whole program versus treating every function/procedure as an ABI symbol), high-level IO abstractions or low-level register (or memory-mapped) IO and interrupt events, etc.
If you're interested in this stuff, you might learn something from reading about PreScheme, which was a lisp dialect designed to allow the runtime system for a full Scheme (lisp dialect) to be written in a more limited Scheme-like language. This is much like the core bits of an OS kernel like Linux are written in carefully controlled subsets of C that do not presume the existence of an underlying runtime environment nor the standard C library.
In reality, many of the compiler and runtime techniques applied to a simple language like lisp could be applied to a C implementation as well. It's really a cultural rather than technical issue which prevents there being C environments that skip the traditional, naive compile and link strategy used in POSIX and UNIX ABIs.
You forget about compilers. LISP gets compiled (by most implementations), too. All the "nifty high level programming shit" can, and sometimes does, if you have a good enough compiler, get compiled away. Furthermore, the "nifty high level programming shit" provides a whole lot more information to the compiler, allowing it to do much more aggressive optimizations because it can prove that they are safe. If somebody comes up with a slick new optimization technique, I don't have to rewrite my LISP code, I just implement it in the compiler. You'd have to go back through every line of C code you've ever written in order to implement it. If somebody gives you a radically different CPU architecture, the C code that is so wonderfully optimized for one CPU will run dog slow. You can reoptimize it for the new arch, but then it will run slow on the old one. With a good LISP compiler, the same code gets optimizations that are appropriate for each arch.
Check out Stalin, SBCL, and http://www.cs.indiana.edu/~jsobel/c455-c511.updated.txt. You might be surprised at what you find.
SIGSEGV caught, terminating
wait... not that kind of sig.