guile-devel
[Top][All Lists]
Advanced

[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




reply via email to

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