Ludovic Courtès wrote:
as well as found a (hopefully good) solution to automatically create
fluids not yet present on reference.
Is each Elisp variable mapped to a fluid? Eventually, you may need VM
instructions for fluid-{ref,set!}, to speed things up.
Yes it is; and I agree that variable references surely have terrible
performance at the moment, because of other things that have to go on
for each reference:
* see if there's a fluid with that name; create if not (but creation is
only done once of course, so the performance hit is from the check only)
* reference the fluid to get the current value
* check if the value is the special elisp void, in which case an error
is reported
So taking this all together, I think there's a lot of potential for
optimization here! Unfortunatly I think that all this is necessary to
ensure the semantics, but two ideas:
1) As you suggested, try doing some parts of this with new VM
operations. Like all of these in one op, or maybe just a "reference and
error on void" as one op, and/or "lookup the variable in some module,
and create it if not there" as another. I think we need some planning
to get the right choice, but it certainly is an important thing for
performance. But for now I'd suggest to keep on with the current
implementation and later see what the real performance bottle-neck is
when running real-world code.
2) I already mentioned some ideas like that before, but if we do careful
analysis of the elisp code, we can probably get rid of some
fluid-references; for instance:
(let ((a 5))
(setq a 1)
(while ... something which references a a lot)
(foobar 1 2 3))
In order to preserve dynamic scoping for a in the call to foobar, we
still have to save a in a fluid as well as do the setq on the fluid
value. But all references to a within the while-loop (if they are
reads) are known to refer to the let-bound a, so we could optimize them
and not take a fluid-ref every now and then.
I think, however, that this can get fairly complicated and need a lot of
tweeking in order to get a sensible optimization. So for now I think we
should try getting the real bottle-necks into VM opterations and see
what that can buy.
There's 1.5 framework. The first one is under `test-suite/tests', used
to test the API. The remaining 0.5 is under `testsuite': it's inherited
from Guile-VM and is used to make sure interpreted and compiled code
yield the same result.
I think the best way would be to add, say,
`test-suite/tests/elisp-compiler.test' (there's already `elisp.test'),
and from there use a macro akin to Andy's `c&e' in `bytevectors.test'.
Ok thanks for the hint! So far I did mainly look into testsuite, but
then I'll take a look at the framework in test-suite and see if I can do
something useful there :)
cheers,
Daniel