I have run the following simple test both on CormanLisp and LispWorks Personal Edition 4.2.0 and found a tremendous difference in the execution times.
(defun tt(nn) (dotimes (n nn) nil))
(time (tt 100000000))
CormanLisp:
Total Execution time: 2.030986 seconds Time spent garbage collecting: 0.0 seconds
LispWorks:
user time = 85.713 system time = 0.140 Elapsed time = 0:01:28 Allocation = 1465806248 bytes standard / 19965 bytes fixlen 0 Page faults
What is it that makes LispWorks work that slow? My guess was a certain compiler option could be turned on so I tried to speed up things by applying the following line from the listener. It made no difference.
> I have run the following simple test both on CormanLisp and LispWorks > Personal Edition 4.2.0 and found a tremendous difference in the execution > times.
> (defun tt(nn) (dotimes (n nn) nil))
> (time (tt 100000000))
Try compiling the function before you run it. In the Listener, you can do: (compile 'tt) Or you can put your definitions in a file and compile-and-load the file.
(With CormanLisp, you don't need to explicitly compile the function, because CormanLisp compiles everything anyway.)
"Ladvánszky Károly" <a...@bb.cc> writes: > I have run the following simple test both on CormanLisp and LispWorks > Personal Edition 4.2.0 and found a tremendous difference in the execution > times.
> (defun tt(nn) (dotimes (n nn) nil))
> (time (tt 100000000))
> CormanLisp:
> Total Execution time: 2.030986 seconds > Time spent garbage collecting: 0.0 seconds
> LispWorks:
> user time = 85.713 > system time = 0.140 > Elapsed time = 0:01:28 > Allocation = 1465806248 bytes standard / 19965 bytes fixlen > 0 Page faults
> What is it that makes LispWorks work that slow? > My guess was a certain compiler option could be turned on so I tried to > speed up things by > applying the following line from the listener. It made no difference.
> I would appreciate any help on how to speed up things.
Just a guess, but I have found I get no useful information back in LispWorks timing anything if I don't put (MP:WITHOUT-PREEMPTION ...) around the call to TIME. (Make sure you debug your program first before doing this, and that you know the wallclock time you expect it to take before you do it, so you don't lock up your process forever.) LW is a multiprocessor and often if you don't do this, in all but the most trivial cases, you get consing overhead that as nearly as I can tell has to do with what other processes are doing, unrelated to your application. Basically, if you run it long enough to get meaningful answers, it's going to schedule unless you inhibit it...
The other thing to know about LispWorks is that it has a large number of optimization qualities and techniques that are non-standard that help it a lot, and if you are only manipulating the CL ones, you are not getting all you could out of it. This might seem "bad" because they are not using the "standard way", but really the standard offers so little hint of what the "meaning" of the optimize qualities are that you can't do any serious optimizing without going outside of what the language promises anyway. Whether you go outside the spec by choosing symbols that are not there or merely by using the existing symbols in ways the meaning of which is not there seems a fine point that I'll not bother to debate.
Finally, on the issue of optimization, I always assume it's not someone's intent in a case like this because I assume people are "good folks" by default, but still as a point of conversational mechanics, I find it precariously close to "flame bait" to simply accuse an implementation of being slow when addressing an out-of-context speed issue on the basis of a simple isolated program that has no commercial value. It just is never going to result in happiness among the conversants, and it's not going to prove much to you at all. I recommend that if you have a serious applicatioo that is getting ready to be deployed (i.e., you're at the point where you should be optimizing and not the epoint where you are just trying to stir up emotions needlessly) and you have a chosen platform (whether it's Corman or LispWorks or Allegro or whatever) and that platform is not meeting your production goals, you talk to the vendor and explain the issue and ask for specific help with your specific needs. That's going to be a lot more productive if you have work to be done. If, on the other hand, you don't have work to be done and just want to stir a bunch of busy people up into a tizzy over a complete non-issue, forcing them to respond because you've created the strawman image that their commercial name is mud and you've veritably forced them to waste time defending it (and, incidentally, keeping them from doing valuable stuff like producing faster implementations in the next release), then just keep right on going as you're going because you're doing just fine... I'll not begin to judge your intent here and leave it to you to just decide how to adjust your presentation and expectations to suit what you really want to have happen here. But the phrase "What is it that makes LispWorks work that slow?" is probably not a correct summary of all the work of all the LispWorks implementors over so many years for you to have made based on as little data as you have done. Better questions to ask might be "Am I doing this right?" "What am I measuring?" "What tools are available to me for tuning?" etc. In spite of its highly generic name, TIME is not an AI tool and doesn't always know quite what you are asking so doesn't always present information about which you can draw such broad sweeping conclusions as you have done here. Even just saying "Why is this program that I wrote appearing to run slowly?" would be less like "fighting words". The focus on your "program" as the topic of discussion is generally important to all discussion of performance since it's programs, not languages, that perform; and the admission that it's "appearance" not "truth" that is potentially under discussion leaves more "wiggle room" for civil discussion.
Apparently, it does unnecessary memory allocation. I have no idea why it needs to allocate memory at all in a dotimes loop like this one. Seems like the LW compiler isn't very good at optimizing dotimes... -- (espen)
> > I have run the following simple test both on CormanLisp and LispWorks > > Personal Edition 4.2.0 and found a tremendous difference in the execution > > times.
> > (defun tt(nn) (dotimes (n nn) nil))
> > (time (tt 100000000))
> Try compiling the function before you run it. > In the Listener, you can do: > (compile 'tt) > Or you can put your definitions in a file and compile-and-load the file.
> (With CormanLisp, you don't need to explicitly compile the function, > because CormanLisp compiles everything anyway.)
Ladvánszky Károly wrote: > I have run the following simple test both on CormanLisp and LispWorks > Personal Edition 4.2.0 and found a tremendous difference in the execution > times.
> (defun tt(nn) (dotimes (n nn) nil))
> (time (tt 100000000))
> CormanLisp:
> Total Execution time: 2.030986 seconds > Time spent garbage collecting: 0.0 seconds
> LispWorks:
> user time = 85.713 > system time = 0.140 > Elapsed time = 0:01:28 > Allocation = 1465806248 bytes standard / 19965 bytes fixlen > 0 Page faults
> What is it that makes LispWorks work that slow? > My guess was a certain compiler option could be turned on so I tried to > speed up things by > applying the following line from the listener. It made no difference.
Can you provide a disassemble listing of the function compiled in Corman Lisp? AFAICT the above function could be optimized to:
(defun tt (nn) nil)
LispWorks 4.2 seems not to do this optimization when using default options or the options you provided. I do not know if there actually is a compiler option setting that would enable such an optimization.
As you can see in the timing results for LispWorks the function conses alot. This is because 100000000 is actually a bignum in LW and so bignum arithmetic is involved. I guess one could optimize this particular issue by splitting up the dotimes loop into several ones with a loop range within the fixnum range.
I guess Corman CL is either optimizing the loop away or is able to fit 100000000 into a fixnum and therefore does fixnum arithmetic.
"Ladvánszky Károly" <a...@bb.cc> writes: > What is it that makes LispWorks work that slow?
That LispWork have 24-bit fixnums, whereas I suppose your other lisp have the property (< 100000000 most-positive-fixnum). If you try with values below (expt 2 23) I assume LispWorks will behave as you expect.
Jochen Schmidt <j...@dataheaven.de> writes: > As you can see in the timing results for LispWorks the function conses alot. > This is because 100000000 is actually a bignum in LW and so bignum
Ah! of course! Now *that* explains a lot.
(I never before noticed that LW has such a low MOST-POSITIVE-FIXNUM, I think a limit of 536870911 is more common among different lisps) -- (espen)
Jochen Schmidt wrote: > I guess Corman CL is either optimizing the loop away or is able to fit > 100000000 into a fixnum and therefore does fixnum arithmetic.
Here are some timings if one splits up the loops so that fixnums get used for indexing:
Thank you for your answer. I do find the first part useful. Regarding the last paragraph, I think you are a little too sensitive. It was not my intent at all to 'accuse an implementation of being slow'. LispWorks is a great tool, this is obvious. My real intent is to find a Lisp implementation that is serious device, that is fast enough for number theory work and that is affordable for me. I felt a bit disappointed that such a simple, trivial test run a magnitude slower than on another Lisp. I have posted my question in hope of finding out what I am doing wrong, as I do beleive LispWorks can run pretty much faster without debug/trace/whatever turned on. Anyway, you are right in saying that it would have been better to ask something like 'What could I do in order to run this test faster on LispWorks?'.
> > I have run the following simple test both on CormanLisp and LispWorks > > Personal Edition 4.2.0 and found a tremendous difference in the execution > > times.
> > (defun tt(nn) (dotimes (n nn) nil))
> > (time (tt 100000000))
> > CormanLisp:
> > Total Execution time: 2.030986 seconds > > Time spent garbage collecting: 0.0 seconds
> > LispWorks:
> > user time = 85.713 > > system time = 0.140 > > Elapsed time = 0:01:28 > > Allocation = 1465806248 bytes standard / 19965 bytes fixlen > > 0 Page faults
> > What is it that makes LispWorks work that slow? > > My guess was a certain compiler option could be turned on so I tried to > > speed up things by > > applying the following line from the listener. It made no difference.
> > I would appreciate any help on how to speed up things.
> Just a guess, but I have found I get no useful information back in > LispWorks timing anything if I don't put (MP:WITHOUT-PREEMPTION ...) > around the call to TIME. (Make sure you debug your program first > before doing this, and that you know the wallclock time you expect it > to take before you do it, so you don't lock up your process forever.) > LW is a multiprocessor and often if you don't do this, in all but the > most trivial cases, you get consing overhead that as nearly as I can > tell has to do with what other processes are doing, unrelated to your > application. Basically, if you run it long enough to get meaningful > answers, it's going to schedule unless you inhibit it...
> The other thing to know about LispWorks is that it has a large number > of optimization qualities and techniques that are non-standard that help > it a lot, and if you are only manipulating the CL ones, you are not getting > all you could out of it. This might seem "bad" because they are not using > the "standard way", but really the standard offers so little hint of what > the "meaning" of the optimize qualities are that you can't do any serious > optimizing without going outside of what the language promises anyway. > Whether you go outside the spec by choosing symbols that are not there or > merely by using the existing symbols in ways the meaning of which is not > there seems a fine point that I'll not bother to debate.
> Finally, on the issue of optimization, I always assume it's not someone's > intent in a case like this because I assume people are "good folks" by > default, but still as a point of conversational mechanics, I find it > precariously close to "flame bait" to simply accuse an implementation of > being slow when addressing an out-of-context speed issue on the basis of > a simple isolated program that has no commercial value. It just is never > going to result in happiness among the conversants, and it's not going to > prove much to you at all. I recommend that if you have a serious applicatioo > that is getting ready to be deployed (i.e., you're at the point where you > should be optimizing and not the epoint where you are just trying to stir > up emotions needlessly) and you have a chosen platform (whether it's > Corman or LispWorks or Allegro or whatever) and that platform is not meeting > your production goals, you talk to the vendor and explain the issue and > ask for specific help with your specific needs. That's going to be a lot > more productive if you have work to be done. If, on the other hand, you > don't have work to be done and just want to stir a bunch of busy people up > into a tizzy over a complete non-issue, forcing them to respond because > you've created the strawman image that their commercial name is mud and > you've veritably forced them to waste time defending it (and, incidentally, > keeping them from doing valuable stuff like producing faster implementations > in the next release), then just keep right on going as you're going > because you're doing just fine... I'll not begin to judge your intent here > and leave it to you to just decide how to adjust your presentation and > expectations to suit what you really want to have happen here. > But the phrase "What is it that makes LispWorks work that slow?" is probably > not a correct summary of all the work of all the LispWorks implementors > over so many years for you to have made based on as little data as you > have done. Better questions to ask might be "Am I doing this right?" "What > am I measuring?" "What tools are available to me for tuning?" etc. > In spite of its highly generic name, TIME is not an AI tool and doesn't > always know quite what you are asking so doesn't always present information > about which you can draw such broad sweeping conclusions as you have done > here. Even just saying "Why is this program that I wrote appearing to run > slowly?" would be less like "fighting words". The focus on your "program" > as the topic of discussion is generally important to all discussion of > performance since it's programs, not languages, that perform; and the > admission that it's "appearance" not "truth" that is potentially under > discussion leaves more "wiggle room" for civil discussion.
"Ladvánszky Károly" <a...@bb.cc> writes: > is a great tool, this is obvious. My real intent is to find a Lisp > implementation that is serious device, that is fast enough for number > theory work and that is affordable for me.
If you actually need the best possible bignum performance, I think nothing beats MCL or OpenMCL (but you would need a mac, of course). -- (espen)
> > What is it that makes LispWorks work that slow?
> That LispWork have 24-bit fixnums, whereas I suppose your other lisp > have the property (< 100000000 most-positive-fixnum). If you try with > values below (expt 2 23) I assume LispWorks will behave as you expect.
lk> is a great tool, this is obvious. My real intent is to find a Lisp lk> implementation that is serious device, that is fast enough for number lk> theory work and that is affordable for me.
ev> If you actually need the best possible bignum performance, I think ev> nothing beats MCL or OpenMCL (but you would need a mac, of course).
CLISP is quite a bit faster than OpenMCL on bignums: see article <wzi4rprgk2n....@laas.fr> [1] for some timings. Károly's tests are IMO much too simple to give a realistic idea of the performance of a particular Common Lisp implementation. See the following page for some information on CL performance benchmarking, with a few results and a test suite that you can download and try for yourself (though several of the tests exceed the heap limits in the no-cost ACL and LW).
Some of the other responses to your question have good general advice.
In your specific case, I think your problem may be simply that you're making Lispworks do bignum arithmetic. On my system, if I broke the dotimes into two seperate nested dotimes things speeded up considerably. I don't have Corman Lisp handy, but perhaps it allows larger fixnums (you might check most-positive-fixnum to see if this is a plausible explanation).
>> As you can see in the timing results for LispWorks the function conses alot. >> This is because 100000000 is actually a bignum in LW and so bignum
>Ah! of course! Now *that* explains a lot.
>(I never before noticed that LW has such a low MOST-POSITIVE-FIXNUM, > I think a limit of 536870911 is more common among different lisps)
For whatever it's worth, I was playing around with the compiler on LispWorks and noticed that the expression
(+ 1 x)
actually resulted in an instruction that added 0x100. Based on this, it seems that on my 32-bit Win2K machine, LispWorks offers 24-bit machine dependant integers. Modifying the lower byte produced truly strange, and presumably dangerous, results. In any event, I was suprised that LispWorks took so many bits for its own purposes, but they are much more expert than I in such matters.
If you are using LW on windows (or linux I think) then one thing to be aware of is that it has quite small fixnums - 24bit I think - and 10^8 is bigger than this. So this loop will probably be doing bignum operations, and will therefore be very slow.
If you simply want to iterate a lot, then you can chunk this into things that are fixnums by iterating over two variables in the obvious way, which will probably result in a fairly dramatic speedup.
>>> As you can see in the timing results for LispWorks the function conses >>> alot. This is because 100000000 is actually a bignum in LW and so bignum
>>Ah! of course! Now *that* explains a lot.
>>(I never before noticed that LW has such a low MOST-POSITIVE-FIXNUM, >> I think a limit of 536870911 is more common among different lisps)
> For whatever it's worth, I was playing around with the compiler on > LispWorks and noticed that the expression
> (+ 1 x)
> actually resulted in an instruction that added 0x100. Based on this, it > seems that on my 32-bit Win2K machine, LispWorks offers 24-bit machine > dependant integers. Modifying the lower byte produced truly strange, and > presumably dangerous, results. In any event, I was suprised that > LispWorks took so many bits for its own purposes, but they are much > more expert than I in such matters.
I remember that there was some correlation to array indexing. There was a thread some while ago about vectors in lispworks and the low array-dimension-limit of it. AFAIR the unix edition has bigger fixnums.
Thank you for your answer, it has been most helpful for me. You are right, most-positive-fixnum is rather small on LW and it is above my 10e8 test count on CormanLisp. That has caused the significant difference in test results. Your simple solution to use nested loops is fine, it runs within 2 secs on my machine.
> Some of the other responses to your question have good general advice.
> In your specific case, I think your problem may be simply that you're > making Lispworks do bignum arithmetic. On my system, if I broke the > dotimes into two seperate nested dotimes things speeded up > considerably. I don't have Corman Lisp handy, but perhaps it allows > larger fixnums (you might check most-positive-fixnum to see if this is > a plausible explanation).
Are you trolling? I don't know if you intended to, but your message really reads like a troll.
As for speeding this function up, how about (defun tt (nn) nil)? Quicker in *any* implementation.
As for the specifics of your question, your loop limit of 100,000,000 is in bignum territory for LWW (it is still a fixnum for Corman), so the difference in cons rate and execution time is simply due to LWW having to fall back to bignums.
When writing benchmarks like this you really need to be careful that you're measuring what you think you're measuring... And try not to be so inflammatory in your titles.
FWIW, for *real world* applications, Lispworks is quite snappy. It's not as good as CMUCL or ACL on the microbenchmarks, but things like your little function don't occur in real code.
> Are you trolling? I don't know if you intended to, but your message > really reads like a troll.
> As for speeding this function up, how about (defun tt (nn) nil)? > Quicker in *any* implementation.
> As for the specifics of your question, your loop limit of 100,000,000 > is in bignum territory for LWW (it is still a fixnum for Corman), so > the difference in cons rate and execution time is simply due to LWW > having to fall back to bignums.
> When writing benchmarks like this you really need to be careful > that you're measuring what you think you're measuring... And try > not to be so inflammatory in your titles.
> FWIW, for *real world* applications, Lispworks is quite snappy. > It's not as good as CMUCL or ACL on the microbenchmarks, but > things like your little function don't occur in real code.
>> > What is it that makes LispWorks work that slow?
>> That LispWork have 24-bit fixnums, whereas I suppose your other lisp >> have the property (< 100000000 most-positive-fixnum). If you try with >> values below (expt 2 23) I assume LispWorks will behave as you expect.
> I *think* it's actually 26 bits, not 24 bits.
On my LispWorks 4.2 on Linux it's 24 bits.
Regards, -- Nils Goesche PGP key ID 0x42B32FC9
"The sooner all the animals are dead, the sooner we'll find their money." -- Ed Bluestone
* "Ladvánszky Károly" <a...@bb.cc> | Trolling??? God, some of you guys here are hypersensitive!
Who you gooa call? Trollbusters!
Actually, I think it is kind of sad that bignums have to be consed all the time instead of being mutable, but it is hard to request non-consing arithmetic operations and the language allows bignums to be passed around without copying, so it is possible that someone may hang on to a value.
/// -- In a fight against something, the fight has value, victory has none. In a fight for something, the fight is a loss, victory merely relief.
Erik Naggum <e...@naggum.net> writes: > * "Ladvánszky Károly" <a...@bb.cc> > | Trolling??? God, some of you guys here are hypersensitive!
> Who you gooa call? Trollbusters!
Great, when I'm covered in marshmallow goo, I'll know who to thank...
> Actually, I think it is kind of sad that bignums have to be consed all > the time instead of being mutable, but it is hard to request non-consing > arithmetic operations and the language allows bignums to be passed around > without copying, so it is possible that someone may hang on to a value.
I totally agree. I have functions like n+ n- n*, etc., for nonconsing arithmetic. I'm hoping to be able to do enough flow analysis that things like:
(loop for i from (1+ most-positive-fixnum) to (* 10 most-positive-fixnum) do (something-not-involving-i))
get compiled to use NINCF, and maybe more impressive things, such as
Of course, n* is potentially-consing, but it's destructive on its first argument. I haven't embarked on this part of the compiler yet, but I can't imagine it'll be too hard, at least for easy things. I can imagine it might take waaay too long for more complex transformations, though.
-- /|_ .-----------------------. ,' .\ / | No to Imperialist war | ,--' _,' | Wage class war! | / / `-----------------------' ( -. | | ) | (`-. '--.) `. )----'
Eric Marsden <emars...@laas.fr> writes: > ev> If you actually need the best possible bignum performance, I think > ev> nothing beats MCL or OpenMCL (but you would need a mac, of course).
> CLISP is quite a bit faster than OpenMCL on bignums: see article
Uh. I forgot that thread. *Blush*.
(I'm quite sure that (Open)MCL is faster than ACL and LW, though) -- (espen)