Evaluation took: 0.1 seconds of real time 0.1 seconds of user run time 0.0 seconds of system run time 0 page faults and 0 bytes consed. NIL
So, we have a factor of 10 win over C :)
What this is probably saying is that the original poster needs to look more carefully at what is being compared; and to remember that simplistic tests don't actually have much to do with the real world.
> Below I have to similar programs one in lisp, the other in C.
> The c program takes about 1 second. > The lisp program takes about 20.
> Is that the best it can do?
Well, firstly, the programs are doing different things. The lisp program should be run with (time (fn)). This will remove the difference created by your user-interaction timing.
Secondly, the lisp program does not have types declared as the C program does. Declaring the types makes a huge difference in execution time, as I will show.
Thirdly, your C program is incorrect in several ways:
You are setting J which is never getting used(no big deal)
You use of "time", on my computer, always prints out either one or two. This is not particularly interesting or helpful.
You are printing a long value, time, but you are only using the format string for an int. This is wrong, wrong, wrong, and can have unpredictable or disturbing results, including core dumps.
To be fair, the lisp program has a problem too; the variable 'j' doesn't come from anywhere. It may be global, but that's yet another way the programs are different. The C program has J as a local variable, which can be a register.
Anyways, using "time" from the unix prompt to time the C program, and using (time (fn)) to test a lisp program with declared types yields the following:
C version : 2.0 (sun cc) C version : 1.33 ( gnu gcc ) Lisp version : 0.19 ( CMU-CL )
(all with no optimizations)
The latter result is interesting. CMU-CL is smart enough to determine that the inner 'i' is a fixnum, and that's all that matters.
In reality, i think this program is a little too simple to use as a benchmark. A lot of compilers will probably optimize the entire program away, as 'j' isn't going anywhere.
> Below I have to similar programs one in lisp, the other in C. > The c program takes about 1 second. > The lisp program takes about 20.
The programs aren't particularly similar -- the C version has a lot of type information in it that the lisp one completely omits. The lisp version also assigns to an undeclared variable, which is probably cripplingly slow.
If you fix these ommissions you might end up with something like this:
ACL seems not to do too well at this without an (optimize speed) declaration, if you put that in then it's pretty comparible with gcc for me. gcc with -O seems to optimize somewhat more aggressively than ACL, and ends up compiling no floating point ops at all. Whether ACL can be made to do that I don't know. CMUCL, which is good at dealing with this kind of tight inner-loop code, seems to compile this significantly better than ACL, though it's still half as fast as gcc (both of these are basically measuring loop overhead for this, as the float stuff is long gone). CMUCL is sometimes significantly worse than ACL for more interesting code than this however.
Of course, benchmarking some more interesting program might be, well, more interesting, and tell you a good deal more about the relative performances. C systems are probably a little faster than typical serious lisp systems where you can reasonably test similar programs, so long as you ignore programmer time, reliability and stuff like that.
> main () { > int h; > int i; > float j = 4.34443; > long l; > l = time(0);
> for (h=0; h < 1000; h++) > for (i=0; i < 10000; i++) {
> j = 4.33452325 * i; > }
> printf("%d", time(0) - l); > }
Sigh. We seem to have this thread about every six months.
First of all, languages are neither slow nor fast. Implementations are.
Second, your programs are not similar.
I compiled your C program on a Linux box with an AMD K6-2 333 MHz and with an optimization flag of -O3 it prints zero, which indicates sub second time used. Without optimization, it prints 1.
Now for the differences between the C program and your lisp program.
First of all, tell the Lisp compiler you're interested in speed:
This is unwise for general use, so don't do this for normal lisp development, but it is the default mode for C.
The first great difference is that you haven't declared your variable j. This means it will be a special variable. In a multithreaded implementation as ACL, this comes with a penalty.
I want to use lisp to deal with processing a stream of video. Do you think that's ridiculous, or can I process data with lisp almost as quickly as a lower level language?
Richard James Panturis Giuly <n...@spam.com> writes:
> Below I have to similar programs one in lisp, the other in C.
> The c program takes about 1 second. > The lisp program takes about 20.
> Is that the best it can do?
No.
First of all, although these programs seem similar, they are not identical. Allow me to modify the code for FN to bring it more in line with what C does.
I'll make H be 10000 because my machine is fast.
First, I'll declare speed 3 and safety 0. I think this is fair considering that C does this by default.
Second, I'll make j be a local variable (as it is in the C program) and tell the compiler its type (which C gets to know as well).
(defun fn1 () (declare (optimize (speed 3) (safety 0))) (let ((j 4.34443)) (declare (single-float j)) (dotimes (h 10000) (dotimes (i 10000) (setq j (the single-float (* i 4.33452325)))))))
The original code performed like this on my machine:
; cpu time (non-gc) 20,530 msec user, 0 msec system ; cpu time (gc) 460 msec user, 0 msec system ; cpu time (total) 20,990 msec user, 0 msec system ; real time 20,990 msec ; space allocation: ; 240 cons cells, 0 symbols, 1,600,000,928 other bytes, 0 static bytes
The code with the declarations performed like this:
; cpu time (non-gc) 972 msec user, 0 msec system ; cpu time (gc) 0 msec user, 0 msec system ; cpu time (total) 972 msec user, 0 msec system ; real time 972 msec ; space allocation: ; 0 cons cells, 0 symbols, -32 other bytes, 0 static bytes
These declarations produced a 21-fold speedup on my machine, you should see a similar performance increase.
Richard James Panturis Giuly <n...@spam.com> writes:
> I want to use lisp to deal with processing a stream of video. Do you > think that's ridiculous, or can I process data with lisp almost as > quickly as a lower level language?
if for some reason you can't make lisp go fast enough, you can call a foreign function (e.g., fortran or C) from lisp. you may want to check out matlisp. this would give some nice matrix functions and provide examples of interfacing to fortran.
-- J o h a n K u l l s t a m [kulls...@ne.mediaone.net] Don't Fear the Penguin!
* Richard James Panturis Giuly <n...@spam.com> | Below I have to similar programs one in lisp, the other in C.
No, you don't. Others have explained why in great detail.
| Is that the best it can do?
The right question for you to ask is "is that the best I can do in Common Lisp?". Others have explained better things you could do in great detail.
I'd like to ask you a different question: What did you expect to learn from this comparison? In my opinion, using naively coded examples with bugs in them is _not_ a good way to compare anything.
#:Erik -- If this is not what you expected, please alter your expectations.
* Richard James Panturis Giuly <n...@spam.com> | I want to use lisp to deal with processing a stream of video. Do | you think that's ridiculous, or can I process data with lisp almost | as quickly as a lower level language?
Well, as general advice, less than 1% of the code of a program is truly speed-sensitive, and you can write the remainder of the code much faster in Common Lisp than in any other language. You won't notice any differences in response time on that code, anyway.
The speed-ciritical code may require special coding, as with a whole lot of type declarations, careful examination of bottlenecks with a profiling tool, etc. Common Lisp environments come with a whole lot of mature tools in this regard. It is not uncommon for a Common Lisp project to drop down to C or assembler to take care of special needs. For instnace, if you're on an Pentium processor, you may find it useful to exploit the Pentium II or Pentium III facilities, and this may be hard to do directly from Common Lisp, while some C or C++ compilers may have reasonable support for them.
More often than not, however, you may be able to experiment with a variety of algorithms in Common Lisp in the time it takes just to write _one_ that works correctly in, say, C++. This aspect of the language is often not appreciated by non-Lispers.
#:Erik -- If this is not what you expected, please alter your expectations.
Richard James Panturis Giuly <n...@spam.com> writes:
> I want to use lisp to deal with processing a stream of video. Do you > think that's ridiculous, or can I process data with lisp almost as > quickly as a lower level language?
It's not ridiculous, but it may be challenging. Do you need to process in real time? If so, you may have to be very careful about GC pauses.
If you are `offline' processing, I don't see a reason why you couldn't use Lisp directly, or use a small C module for the intensive stuff and Lisp for the higher level stuff.
> Centuries ago, Nostradamus foresaw a time when Erik Naggum would say: > >* Richard James Panturis Giuly <n...@spam.com> > >| Below I have to similar programs one in lisp, the other in C.
> > No, you don't. Others have explained why in great detail.
> >| Is that the best it can do?
> > The right question for you to ask is "is that the best I can do in > > Common Lisp?". Others have explained better things you could do in > > great detail.
> > I'd like to ask you a different question: What did you expect to > > learn from this comparison? In my opinion, using naively coded > > examples with bugs in them is _not_ a good way to compare anything.
> Actually, I think the example is _quite_ useful, from a pedagogic > standpoint.
> The programs _appear_ to do "the same thing," and the process of > describing how to tune the Lisp version to perform better is reasonably > instructive, at least to the relatively naive user.
> It does not require either: > a) A lot of verbiage, or > b) Anything _tremendously_ complex, conceptually, > to show how to make the Lisp code run lots faster.
> It is also interesting to note that most of the techniques suggested > _won't_ do much good with CLISP, and it would be instructive to look at > _why_ that is, as well.
I can attest to what you're saying-- as a "naive lurker" I found it instructive (especially the one that pointed out that it would be optimized entirely away!).
> I want to use lisp to deal with processing a stream of video. Do you > think that's ridiculous, or can I process data with lisp almost as > quickly as a lower level language?
Actually, I don't really know how fast your program must run.
In my opinion, it is not ridiculous at all to expect good speeds with lisp programs, provided that you follow some implementation-dependent optimization techniques. I recommend CMU/CL which seems to permit the best speeds. The techniques for optimization are often easy to apply, even if there are many cases where I simply get lost (problems in understanding CMU/CL documentation).
For instance, I developped with 4 comrades a small OpenGL subset in Common Lisp, using CMU/CL. We finally managed to get 1/4 of the speed of MesaGL in average, with the possibility to go up to 1/2 (university project in limited time). We really enjoyed using Common Lisp which gives so many convenient features and gives you a better view over your programs. This also permits more advanced optimizations.
But if you really need high speed, maybe you should consider assembly code only for the time-consuming functions. Notice that you really can call such speedy functions from CMU Common Lisp, allying convenience of the language with optimal execution speeds. That is what companies (Naughty Dog, Nichimen) tend to do when they need terrific speeds for 3d engines, for instance...
I hope I helped you, I'd really like to know if you will manage to make it in Common Lisp and how. My knowledge in CMU/CL optimization techniques needs to be completed...
-- ---------------------------------------------- Jonathan BAILLEUL (baill...@emi.u-bordeaux.fr) Maitrise Informatique, Universite Bordeaux I Currently attending Berkeley Summer Session Courses CS61a/CS3
> Richard James Panturis Giuly <n...@spam.com> writes:
> > I want to use lisp to deal with processing a stream of video. Do you > > think that's ridiculous, or can I process data with lisp almost as > > quickly as a lower level language?
> It's not ridiculous, but it may be challenging. Do you need to > process in real time? If so, you may have to be very careful about GC > pauses.
Yes. This can be avoided in avoiding consing as much as possible. Sometimes it requires handling by hand pre-allocated pools of memory (Paul Graham's ACL) or forcing certain types (floating-points) to use non-descriptor representation. I'd like extra help on this topic under CMU/CL, as far as some special cases cause problems in my programs...
> If you are `offline' processing, I don't see a reason why you couldn't > use Lisp directly, or use a small C module for the intensive stuff and > Lisp for the higher level stuff.
-- ---------------------------------------------- Jonathan BAILLEUL (baill...@emi.u-bordeaux.fr) Maitrise Informatique, Universite Bordeaux I Currently attending Berkeley Summer Session Courses CS61a/CS3
Centuries ago, Nostradamus foresaw a time when Erik Naggum would say:
>* Richard James Panturis Giuly <n...@spam.com> >| Below I have to similar programs one in lisp, the other in C.
> No, you don't. Others have explained why in great detail.
>| Is that the best it can do?
> The right question for you to ask is "is that the best I can do in > Common Lisp?". Others have explained better things you could do in > great detail.
> I'd like to ask you a different question: What did you expect to > learn from this comparison? In my opinion, using naively coded > examples with bugs in them is _not_ a good way to compare anything.
Actually, I think the example is _quite_ useful, from a pedagogic standpoint.
The programs _appear_ to do "the same thing," and the process of describing how to tune the Lisp version to perform better is reasonably instructive, at least to the relatively naive user.
It does not require either: a) A lot of verbiage, or b) Anything _tremendously_ complex, conceptually, to show how to make the Lisp code run lots faster.
It is also interesting to note that most of the techniques suggested _won't_ do much good with CLISP, and it would be instructive to look at _why_ that is, as well. -- cbbro...@hex.net - <http://www.ntlug.org/~cbbrowne/lisp.html> "Some sins carry with them their own automatic punishment. Microsoft is one such. Live by the Bill, suffer by the Bill, die by the Bill." -- Tom Christiansen
>> Centuries ago, Nostradamus foresaw a time when Erik Naggum would say: >> >* Richard James Panturis Giuly <n...@spam.com> >> >| Below I have to similar programs one in lisp, the other in C.
>> > No, you don't. Others have explained why in great detail.
>> >| Is that the best it can do?
>> > The right question for you to ask is "is that the best I can do in >> > Common Lisp?". Others have explained better things you could do in >> > great detail.
>> > I'd like to ask you a different question: What did you expect to >> > learn from this comparison? In my opinion, using naively coded >> > examples with bugs in them is _not_ a good way to compare anything.
>> Actually, I think the example is _quite_ useful, from a pedagogic >> standpoint.
>> The programs _appear_ to do "the same thing," and the process of >> describing how to tune the Lisp version to perform better is reasonably >> instructive, at least to the relatively naive user.
>> It does not require either: >> a) A lot of verbiage, or >> b) Anything _tremendously_ complex, conceptually, >> to show how to make the Lisp code run lots faster.
>> It is also interesting to note that most of the techniques suggested >> _won't_ do much good with CLISP, and it would be instructive to look at >> _why_ that is, as well.
>I can attest to what you're saying-- as a "naive lurker" I found it >instructive (especially the one that pointed out that it would be >optimized entirely away!).
>So, why does it do no good with CLISP?
Because CLISP doesn't provide the (declaim) options that are common with other Common Lisps, and, more notably, because it doesn't compile to assembly language, and thus provide _substantial_ optimizations.
Sample:
Running the bit of code: (defun fn () (let (j) (dotimes (h 1000) (dotimes (i 10000) (setf j (* 4.33452325 i)))))) (time (fn))
with CLISP, three times: a) Compiled, via "clisp -c out.lsp" b) Compiled, via "clisp -c outfast.lsp", with the "declaim" options added in c) Not compiled.
Copyright (c) Bruno Haible, Michael Stoll 1992, 1993 Copyright (c) Bruno Haible, Marcus Daniels 1994-1997 Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998 Copyright (c) Bruno Haible, Sam Steingold 1999
[1]> (load "out.fas") ;; Loading file out.fas ... Real time: 10.876239 sec. Run time: 8.69 sec. Space: 72 Bytes ;; Loading of file out.fas is finished. T [2]> (load "outfast.fas") ;; Loading file outfast.fas ... Real time: 10.951782 sec. Run time: 8.69 sec. Space: 72 Bytes ;; Loading of file outfast.fas is finished. T [3]> (load "out.lsp") [runs for several minutes without respite...]
It's definitely _vastly_ faster to "precompile" CLISP code; that still leaves you with runtimes that are decidedly not impressive. -- cbbro...@acm.org - <http://www.hex.net/~cbbrowne/lisp.html> Of course, unless one has a theory, one cannot expect much help from a computer unless _it_ has a theory)... -- Marvin Minsky
Richard James Panturis Giuly <n...@spam.com> writes:
>I want to use lisp to deal with processing a stream of video. Do you >think that's ridiculous, or can I process data with lisp almost as >quickly as a lower level language?
Well, if it's real-time, you may get into conflict with the Garbage Collector.
Looking at your previous posting, the first thing you need is to turn on maximum warning level on your C compiler. The second thing to do is to compile your code on CMUCL, even if your final version should run on a different Lisp. CMUCL compiler emit a lot of message that help you to make your code fast.
There are no "real" problems with Common Lisp reaching what I'd call "raw machine speed". Minor problems are that the declarations in Lisp are ugly and hard to write, so that you loose some of Lisp's advantage. Using objects from classes in the classical sense in Lisp (CLOS) is a lot slower than C++ or Objective-C, but for raw speed you don't want that anyway.
A somewhat more serious problem is that some source file layout forms may affects current Lisp compilers more than current C compilers. If your application is spread over several source files, you cannot use function from a different files as inline functions. That applies to both Lisp and C. But in Lisp at least CMUCL introduces additional overhead for calling real functions. It forces argument checks and the return value is always boxed. But if you're really other speed, you don't want sperate compilation in either C or Lisp anyway.
I agree to what other said that Lisp makes it a lot easier to experiment with different algorithms and data structures than C does. If you overlook a better alorithm, the whole boxed-vs-direct value, garbage collection etc. is absolutely irrelevant.
I don't agree to the "hot spots" view. For me, when I design an application from a well-defined specification with performance in mind, I have some hot spots in the initial try and eliminate them after the first profiling session, a matter of less than on hour. After that, my applications are usually no longer subject to speed up through local changes. If your programming is the same way, that has far-reaching consequences, especially that using some C functions in your Lisp program doesn't buy you much.
> I want to use lisp to deal with processing a stream of video. Do you > think that's ridiculous, or can I process data with lisp almost as > quickly as a lower level language?
It would be interesting if someone with greater experience could explain how to handle the GC delay in this sort of realtime applications... O:-)
I wonder if any lispers have ever heard of Newmonics? They are a company that specializes in real time Java (boo, hiss). But they supposedly have a "real time garbage collector". A few years back I thought they were working on hardware-assisted garbage collection, but from just visiting their web site I don't see anything about hardware assist. See www.newmonics.com.
In article <0D_a5.154$5d3.2...@m2newsread.uni2.es>, "Fernando Rodríguez" <f...@mindless.com> wrote:
> "Richard James Panturis Giuly" <n...@spam.com> escribió en el mensaje > news:396B7E25.F67E096F@spam.com... > > I want to use lisp to deal with processing a stream of video. Do you > > think that's ridiculous, or can I process data with lisp almost as > > quickly as a lower level language?
> It would be interesting if someone with greater experience could explain > how to handle the GC delay in this sort of realtime applications... O:-)
> The right question for you to ask is "is that the best I can do in > Common Lisp?". Others have explained better things you could do in > great detail.
You are correct. My wording was bad because I was in a hurry and afraid that lisp was 20 times slower that C. That would have messed up my plans pretty badly.
"Fernando Rodríguez" <f...@mindless.com> writes: > "Richard James Panturis Giuly" <n...@spam.com> escribió en el mensaje > news:396B7E25.F67E096F@spam.com... > > I want to use lisp to deal with processing a stream of video. Do you > > think that's ridiculous, or can I process data with lisp almost as > > quickly as a lower level language?
> It would be interesting if someone with greater experience could explain > how to handle the GC delay in this sort of realtime applications... O:-)
It depends on how `real time' you need to be.
If there are certain times where you cannot tolerate a GC, but for the most part you can, then you can simply let the application CONS when it has to (either let it gobble as much memory as it wants, or run the GC just before the critical part so there is enough room, or pre-allocate the amount it needs).
If your application can be made to not CONS during the real-time part of its operation, there is no need to GC during those parts.
If your application can get away with `fast response' or `almost real time', a correctly tuned generational GC will probably do the trick.
If you need `hard real time' response, but also need to let the application cons at will, an `incremental' GC can do it. An `incremental' GC does a bounded amount of work per cons, so you can guarantee a real upper bound on response. But since these can be tricky to code, it might be easier to just buy a lot of ram and go with the first option.
In article <8kiaej$rb...@nnrp1.deja.com>, johnc...@my-deja.com wrote: > I wonder if any lispers have ever heard of Newmonics? They are a > company that specializes in real time Java (boo, hiss). But they > supposedly have a "real time garbage collector".
Harlequin has a realtime GC for Lisp which has been used projects. As I understand the GC of ACL is widely tuneable and one might get certain capabilities by setting the right switches. Symbolics also has been using their system in realtime environments, AFAIK.
* "Fernando Rodríguez" <f...@mindless.com> | It would be interesting if someone with greater experience could explain | how to handle the GC delay in this sort of realtime applications... O:-)
Well, suppose you have a stream that produces about 50 M/s, your maximal GC delay is 100 ms, and your processing ability is above 50 M/s, you can set up output buffers of about 5 M, which you would fill before starting actual output and which would drain during GC, coupled with an input buffer that would fill up during GC and be drained faster than new input is filling it.
Nobody would ever notice any GC pauses. All you would see is 100 ms processing latency without any reduction in bandwidth.
If you can control the input bandwidth and read and process faster than you need to output, your application would block on output and you wouldn't need to worry about GC pauses at all if you set up big enough output buffers.
The key is really to have faster-than-real-time processing power.
#:Erik -- If this is not what you expected, please alter your expectations.