This is the mail archive of the guile@sourceware.cygnus.com mailing list for the Guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Kill the SCM_NIMPs


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]