[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Elisp performance
From: |
Neil Jerram |
Subject: |
Re: Elisp performance |
Date: |
Thu, 30 Jul 2009 21:18:54 +0100 |
User-agent: |
Gnus/5.11 (Gnus v5.11) Emacs/22.2 (gnu/linux) |
Daniel Kraft <address@hidden> writes:
> Lambda arguments are still always dynamically bound, which is quite a
> pity as it inhibits tail-call optimization;
This prompted me to wonder if using fluids is the best way to
implement dynamic binding.
Perhaps I'm forgetting something basic, but surely it's using
`dynamic-wind' that gives us dynamic binding semantics, not fluids.
(Note that `with-fluids', which is probably the closest thing in Guile
Scheme to a dynamic let, is a combination of `dynamic-wind' and
`fluid-set!'.)
The main thing I believe that makes a fluid different from a normal
variable is that a fluid can have a different value in each thread -
which is not relevant to Elisp.
So what's my point? I'm not sure, just musing. As far as performance
and tail-call optimization are concerned, I would guess that the main
thing that needs to be addressed in order to reinstate tail-call
optimization would be the dynamic wind - i.e. the compiler knowing
that it isn't necessary to set up another dynamic-wind frame, it can
just jump with the current variables.
> 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.
(Also, if I get time, I'll try this with the old translation code
too. Just for fun, and hopefully for confirmation that the new
approach is much better!)
> My conjecture is that the remaining bottle-neck are the primitive
> calls, as they are still resolved using the dynamic-binding and fluid
> mechanisms; so maybe it is really a good idea to change function
> bindings to just global ones without dynamic scoping, and implement
> flet/flet* with dynamic-wind. In contrast to variables, for functions
> access performance is a lot more important than let performance, I
> guess, so this might be the way to go. What do you think?
See above. I'm not sure why fluid access should be significantly
slower than non-fluid access, so I would guess that the performance
cost is coming from the dynamic-wind part.
Regards,
Neil