This is the mail archive of the
guile@sourceware.cygnus.com
mailing list for the Guile project.
Re: Making Guile slower?
- To: Mikael Djurfeldt <mdj at mdj dot nada dot kth dot se>
- Subject: Re: Making Guile slower?
- From: Greg Harvey <Greg dot Harvey at thezone dot net>
- Date: 16 Dec 1999 05:57:25 -0330
- Cc: guile at sourceware dot cygnus dot com, mvo at zagadka dot ping dot de, jimb at red-bean dot com, orre at nada dot kth dot se, djurfeldt at nada dot kth dot se
- References: <19991216034642.19077.qmail@sourceware.cygnus.com> <xy7hfhj1f2t.fsf@mdj.nada.kth.se>
Mikael Djurfeldt <mdj@mdj.nada.kth.se> writes:
> [I'm resending this message under a more proper subject line. Also,
> one additional thing: Note that we can't make some proper mix of
> these two approaches---that would be totally confusing. We have to
> decide whether to always make these, sometimes unneccesary, tests for
> nonimmediateness or to always give the programmer control over this.
>
> And, btw, a "fair" test is to find that worst-case situation which is
> still a computation of reasonable use. You have to find code in
> Guile where this change matters.]
This is about as close to biased against using the nimp tests as you
can get: it sort of simulates repeatedly calling a big pile of if
statements where you do mod_count SCM_FOOP macros (in this case, I
used SCM_VECTORP), and one of those modifies the value.
#include <libguile.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
double
time_thunk1(void (*thunk)(void *a), void *arg)
{
clock_t start, end;
double elapsed;
start = clock();
thunk(arg);
end = clock();
elapsed = ((double) (end - start)) / CLOCKS_PER_SEC;
return elapsed;
}
int iterations = 1000000;
int mod_count = 10;
void
imp_test(void *arg)
{
SCM foo = (SCM) arg;
register int i;
for(i = 0; i < iterations; i++) {
if(SCM_NIMP(foo) && SCM_VECTORP(foo)) {
if(!(i%mod_count)) {
SCM_SETCDR(foo, SCM_MAKINUM(1));
}
}
}
}
void
no_imp_test(void *arg)
{
SCM foo = (SCM) arg;
register int i;
for(i = 0; i < iterations; i++) {
if(SCM_VECTORP(foo)) {
if(!(i%mod_count)) {
SCM_SETCDR(foo, SCM_MAKINUM(1));
}
}
}
}
int
main(int argc, char **argv)
{
scm_cell foo;
double res;
if(argc >= 2)
iterations = strtol(argv[1], NULL, 10);
if(argc == 3)
mod_count = strtol(argv[1], NULL, 10);
foo.car = scm_tc7_vector;
foo.cdr = SCM_MAKINUM(1);
printf("With nimp check: %i iterations\n", iterations);
res = time_thunk1(imp_test, &foo);
printf("Time: %f\n", res);
printf("Without nimp check: %i iterations\n", iterations);
res = time_thunk1(no_imp_test, &foo);
printf("Time: %f\n", res);
return 0;
}
I also tried it malloc as the thing being done to the cell, instead of
just setting it to an inum, but I got some odd results. In fact, I got
overall odd results:
With nimp check: 1000000 iterations
Time: 0.010000
Without nimp check: 1000000 iterations
Time: 0.100000
[greg ~/devel/tests]$ ./imp 1000000 100
With nimp check: 1000000 iterations
Time: 0.010000
Without nimp check: 1000000 iterations
Time: 0.110000
Etc. So I thought it might be a cache thing, so I made a nonimp.c
file. Same results. So I thought that maybe SCM_VECTORP was too
complicated, so I tried SCM_CONSP:
With nimp check: 1000000 iterations
Time: 0.010000
Without nimp check: 1000000 iterations
Time: 0.130000
I thought maybe it was getting a hint that foo isn't changing, so I
added a SETCAR(foo, rand()); inside each loop, making sure that they
used the same seed value.
[greg ~/devel/tests]$ ./imp
With nimp check: 1000000 iterations
Time: 0.420000
Without nimp check: 1000000 iterations
Time: 0.460000
And so on. In any case, I think it's a pointless bit of pennypinching
to worry about one test in the vast pile of code that is guile,
particularly if it makes it less likely to introduce bugs.
--
Greg