This is the mail archive of the
guile@sourceware.cygnus.com
mailing list for the Guile project.
Re: Kill the SCM_NIMPs
- To: Dirk Herrmann <dirk at ida dot ing dot tu-bs dot de>
- Subject: Re: Kill the SCM_NIMPs
- From: Mikael Djurfeldt <mdj at mdj dot nada dot kth dot se>
- Date: 06 Jan 2000 20:19:31 +0100
- Cc: Guile Mailing List <guile at sourceware dot cygnus dot com>
- Cc: djurfeldt at nada dot kth dot se
- References: <Pine.LNX.4.21.0001061816260.2598-100000@marvin.ida.ing.tu-bs.de>
Dirk Herrmann <dirk@ida.ing.tu-bs.de> writes:
> After Greg's famous patch, it has been possible to get rid of a thousand
> calls to SCM_NIMP. My believe is, that SCM_NIMP and also SCM_IMP are
> extremely low level structures that should be very rarely used. However,
> I realized that there are still quite a lot of them. Looking closer, I
> figured out that many of these are just used as a replacement for
> SCM_NNULLP (or SCM_NULLP), for example when cdr'ing along a variable that
> is known to be a list.
>
> The funny thing (after having that infamous cycle-counting debate) is,
> that when you look at the implementation of SCM_NIMP and compare that
> with SCM_NNULLP you realize, that SCM_NNULLP is only a comparison of a SCM
> value with the constant SCM_EOL, while SCM_NIMP requires to extract a
> single bit from a SCM value.
Well, I hope it should be clear by now that
1. Both Marius and me have from very early on welcomed the
substitution of SCM_FOOP (X) for SCM_NIMP (X) && SCM_FOOP (X).
2. The debate was about principles for making changes to Guile: the
principle of making changes in a way that you don't loose
information, and, the principle of making changes in a way that we
don't successively slide down the slippery slope of cumulative
penalties. I do think both of these principles are very important
to follow.
3. I had great admiration for Greg before the debate, and I have great
admiration for Greg now.
Regarding the difference in efficiency between SCM_NIMP and
SCM_NNULLP, I don't think it is of any relevance. Both usually
generate one instruction.
(If there is any difference at all, my guess is that SCM_NIMP is
faster, since SCM_NNULLP needs to read an immediate 32-bit value for
the comparison while SCM_NIMP uses a smaller value. I do think
bitoperations are quite efficient on most CPUs. In any case they were
at the time SCM was written.)
> It's just a guess, but I assume that using SCM_NIMP instead of SCM_NNULLP
> (in places where it is appropriate) is not only obfuscating the
> semantics of the code, but also might lead to a performance penalty.
>
> Example: This code is extracted from backtrace.c
>
> -------------------------------------------------------------------------
> SCM_DEFINE (scm_set_print_params_x, "set-print-params!", 1, 0, 0,
> (SCM params),
> "")
> #define FUNC_NAME s_scm_set_print_params_x
> {
> int i, n = scm_ilength (params);
> SCM ls;
> print_params_t *new_params;
> SCM_ASSERT (n >= 1, params, SCM_ARG2, FUNC_NAME);
> for (ls = params; SCM_NIMP (ls); ls = SCM_CDR (ls))
> SCM_ASSERT (scm_ilength (SCM_CAR (params)) == 2
> ...
> -------------------------------------------------------------------------
>
> First, the assertion makes sure that 'params' is a proper list and has at
> least one element. From then on, SCM_NIMP is used to test whether the end
> of that list is reached. Obviously, the use of SCM_NNULLP would much
> closer reflect the semantics.
If you think I used SCM_NIMP in order to gain efficiency that's
definitely not the case. This is not a time critical part of the
interpreter.
I also agree that SCM_NNULLP reflects the semantics better.
I wrote SCM_NIMP just because it has been a convention in Guile's
internals to test for end-of-list like that. I believe in following
conventions when such exist. I don't mind if this convention is
changed, but it is probably a good idea to do make the change at all
places.
Thanks for your many and good contributions!
/mdj