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."
In speed and elegance, perhaps. But not on the überprogrammer salary to maintain it.
It's disgusting that these LISPers aren't content with their own perversion, but have to try to attract others to the gay lifestyle.
Not at the expense of having to learn LISP! I'd rather use dialup.
And Java is faster too!
(rolls eyes)
Different tools are good for various solving various problems.
Yeah, I know certain library routines in certain languages are better than others.
Interpreted languages, in general, are not faster than compiled languages. Period.
This "faster than C" canard keeps getting trotted out and shot down every time.
Well, there is one language faster: assembly.
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.
In speed and elegance, perhaps.
So you agree to the fact that emacs is faster and more elegant than vi, right ? You agree ?
Based on my theoretical understanding of how computers work, I though HTTP daemon performance depended mostly on
Would someone care to correct me?
Note that TFA (well, the slideshow) measures performance in requests per second. That's a very useful measure, but it's compared to Ruby (Mongrel?) and PHP (Apache?). I'm not sure what that comparison means. Does Apache not support lisp, or only as CGI?
Is there something stopping Apache from being sped up? Is he measuring the performance of LISP, or the performance of a HTTP daemon?
I'm a bit confused...
Of course, this guy didn't benchmark against any modern performance kings, such as Nginx, YAWS, htstub or LightStreamer.
There is no reason to believe this is the world's fastest webserver, and I'm sure as hell not holding my breath.
StoneCypher is Full of BS
... so I guess it's not fast enough.
We do that on Nov 11, thanks. I don't see why we need to adopt your dates for the purpose.
But... but... Nov. 11th is a horrible date for outdoor grilling! That would ruin the holiday entirely. I don't think you really grasp what Memorial Day is all about...
"Convictions are more dangerous enemies of truth than lies."
Reason being is that C is the closest high level language to how a processor actually operates. A lot of people get confused, or perhaps never really know how a CPU actually works and that no matter what language you code in, it all gets translated in to machine language in the end.
Now what that means is that there are certain things that, while convenient for humans, have nothing to do with how the processor actually thinks. A good example would be newer replacements for pointers. A lot of people hate pointers, they claim, correctly, that pointers are confusing, and that you can easily cause problems with them. That is all true, however it is also how the CPU actually thinks. The CPU doesn't have advanced concepts of references and of garbage collection and so on. The CPU has data in memory, and pointers to the location of that data. It doesn't even have data types. The data is just binary data. You can store a string, and then run calculations on it using the FPU. Granted you'll get garbage as a result, but there's nothing stopping you from doing it, the CPU has no idea what your data is.
So, the upshot of this is that C is very close to the bare metal of how the system works. Thus if you are good with it, you can produce extremely efficient code. The higher level stuff may be nice, but it all slows things down. When you have a managed language that takes care of all the nasty stuff for you, well it is spending CPU cycles doing that. Now the tradeoff is quite often worth it, since CPUs have loads of power and maintainability of code is important, but don't trick yourself in to thinking it is more efficient.
You have to remember that no matter what, there is one and only one way that the machine actually thinks, one way it actually processes information. All the nifty high level programming shit is just to make life easier for the programmers. That's wonderful, but it doesn't give you the most optimized code. Of the high level languages, C retains that crown, and likely always will, because it is the closest to how a CPU actually works. I've seen the joke that "C is a language with all the speed of assembly and all the ease of use of assembly!" There's some truth to that.
So I have to agree with the grandparent. If the LISP heads think LISP is faster than C, they are kidding themselves. I'm not saying a good LISP program can't be faster than a bad C program, but if you have equal skill in optimization, sorry C will win out because in the end it will generate more efficient machine code and that's all that matters. All the theory of different programming paradigms in the world isn't relevant to how the CPU is actually going to do things.
Once you get things like branch prediction, speculative execution and pipelining into the picture, no, C isn't really any closer to how the processors operate. Making efficient use of a modern CPU involves detail at a much, much lower level than C exposes.
The performance killer for high-level languages isn't really the abstraction away from the machine instruction set; it's garbage collection. And even then, it's mostly because GC tends not to play well with memory caches and virtual memory; a simple stop-and-copy garbage collector is actually algorithmically more efficient than malloc/free, but absolutely atrocious with caches and VM.
Are you adequate?
Repost - lt should be replaced by lessthan sign...
Trolling sure sounds easy, but...
Gambit-C Scheme vs. C
I'll make it easy for you. It's the two minute litmus test. Even easier -- I'll give you the pseudo-C code:
Task: compute n! for n >= 1000.
In Scheme (Gambit 4.2.8, using infix):
int factorial(int n) {
if (n lt= 0) {
1;
} else {
n * factorial(n - 1);
}
}
compile with: gsc f.six
and run it:
gsi
Gambit v4.2.8
> (load "f")
"/home/user/f.o1"
>(factorial 1000)
4023...0000
Your challenge? Write a C version in two minutes, tested and compiled. Now, as the final icing, run the C version on smaller numbers, and compare the performance -- did you forget to compile in small integer versions? (try factorial(12) a million times).
I'll wait (another two minutes). Compare the performance against the LISP version. Did you have to write two versions -- one for big integers and one for small integers? That is pretty well the only way to keep a speed advantage... I hope you wrote it that way. Did you remember to put in 32/64 bit conditionals to retain your advantage on a 64 bit platform?
I think your C code now looks like this (it should):
#define FACT_LIMIT 12 -- for 32 bit int type, I don't know what the cutoff is for 64 bit. /* This only gets executed a maximum of FACT_LIMIT times; leave it recursive */ /* May wish to rewrite to an iterative form */
#include bignum.h -- I don't want to bother with quoting assume angle brackets
int fact_integer(int n) {
if (n lt= 0) {
return 1;
} else {
return n * factorial(n - 1);
}
}
bignum factorial(bignum n) {
if (compare_lt(n, FACT_LIMIT)) {
return int_to_bignum(fact_integer(bignum_to_int(n)));
}
return bignum_mult(n, bignum_dec(n));
}
You choose the bignum package to use. Or, for more fun, write it yourself. If you wrote it yourself, you remembered to switch to FFT style multiplication at bigger sizes? Or Karatsuba?
Now, we have only coded to a recursive form, but, since bigints are not first-class in C, we don't know about memory reclamation (leakage). I hope you know the gmp library, or can roll up a gee-whiz allocator on your own. The gmp library would be cheating, by the way -- YOU DID CLAIM YOUR IMPLEMENTATION IN C.
If recursion is viewed as a problem, the Gambit-C version can be recoded as:
int factorial(int n) {
int i;
int a;
if (n lt= 0) {
1;
} else {
a = 1;
for (i = 1; i lt= n; ++i) {
a *= i;
}
a;
}
}
I am sure that something equivalent can be done in the C version. But the normal flow of control stuff doesn't know about bignums. We COULD make the incoming parameter an int, I guess... which works for factorial() but may not be as workable for other functions.
Answers:
- gmp does better than Gambit-C on bigint multiply, using FFTs.
- breaking the result into two separate functions is needed for C to come ahead.
- yes, C is faster, at the expense of a lot more programming.
- if I want to, I can simply drop C code into my Gambit-C program on an as-needed basis. The Gambit-C code still looks a
whole lot cleaner than the C version, and ties it for small integer performance. The bigint performance is still a "win" for
gmp, but I can use THAT package directly as well in Gambit-C.
Win:
- Gambit-C. The prototype was finished to spec in two minutes. Optim
Just another "Cubible(sic) Joe" 2 17 3061