guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Elisp performance


From: Daniel Kraft
Subject: Re: Elisp performance
Date: Fri, 31 Jul 2009 17:14:27 +0200
User-agent: Thunderbird 2.0.0.0 (X11/20070425)

Hi Ken,

Ken Raeburn wrote:
On Jul 31, 2009, at 02:02, Daniel Kraft wrote:
Iterative prime sieve, (length (find-primes-to 5000)):
 Scheme: 0.42s
 Elisp, no void checks, lexical let: 3.40s
 Elisp, no void checks, dynamic let: 4.43s
 Elisp, void checks, dynamic let: 5.12s
 Elisp, void checks, lexical let: 4.06s
As Ken says, it would be good to see an Emacs timing too.

I'd like to provide one, but have no idea how to do so... I just managed to find out how to evaluate elisp code from a buffer, but it would be cool to get some elisp REPL if possible (maybe even without starting emacs itself and just from a shell?) -- and how to I time? As well as byte-compile and time then?

[...]

Thanks for the emacs hints! For the prime sieve, emacs itself takes about 1.89s (interpreted) and 0.32s (compiled). So it's significantly faster than my elisp version at the moment, the reason might be the performance hit from the primitive calls already discussed (but I don't know). And the compiled version is even faster than Guile runs the Scheme code.

The "tight loop" takes in emacs about 0.91s (interpreted) and 0.26s (compiled) when using lexical-let and 0.58s / 0.16s when using dynamic binding. So with the manual guile-primitive hack, my version actually reaches emacs here; which is still quite unfair of course, as my code is faster with lexical-let and emacs is slower...

Ok, I guess a quick summary is in order: I think implementing dynamic binding directly using dynamic-wind instead of with fluids is a good idea, as long as we don't already want to keep the fluids for future multi-threading. If this ever comes, we are probably again forced back to fluids. Do you think we should switch or not? Regarding tail calls, my opinion is that there's no "easy" way to make them work with dynamically bound arguments (as arguments are in elisp), if there is at all -- and that we should not bother. I don't think emacs does general tail-call optimization (does it?), and there will be a way to switch lambda arguments back to lexical scoping, so that for those lambda's tail-calls will be optimized just fine with the current compiler/VM infrastructure.

If the new thread keeps running while the creating thread exits the scope that created a dynamic binding, while the new thread wants to keep using or updating it... ugh.

Yep, so I think we should either make dynamic bindings thread local (keep the fluids) or make them global with the problems of concurrent access but simply declare they are unsafe to use with multiple threads and users should instead use lexical bindings in relevant code.

I did not get your opinion about which of these ways to go for dynamic bindings... From my point of view, both have quite advantages and disadvantages; fluids are cleaner and can be used in the multi-threaded context (should it become topical), but getting rid of them with dynamic-wind promises better performance and simpler working when single threaded. Maybe we could even provide both implementations to choose for the user, I'll investigate how much effort that would be and what problems there arise.

Yours,
Daniel

--
Done:  Arc-Bar-Cav-Ran-Rog-Sam-Tou-Val-Wiz
To go: Hea-Kni-Mon-Pri




reply via email to

[Prev in Thread] Current Thread [Next in Thread]