Hi, David Kastrup <d...@gnu.org> skribis:
> Ludovic Courtès <l...@gnu.org> writes: [...] >> Thus we could go with the patch below, though I doubt it would make a >> measurable difference (and it actually adds tests for other cases). > > It made a considerable measurable difference in LilyPond You measured with and without the patch I sent? Or something else? >> diff --git a/libguile/eq.c b/libguile/eq.c >> index 627d6f09b..16c5bfb3f 100644 >> --- a/libguile/eq.c >> +++ b/libguile/eq.c >> @@ -303,6 +303,8 @@ scm_equal_p (SCM x, SCM y) >> return SCM_BOOL_F; >> if (SCM_IMP (y)) >> return SCM_BOOL_F; >> + if (scm_is_symbol (x) || scm_is_symbol (y)) >> + return SCM_BOOL_F; >> if (scm_is_pair (x) && scm_is_pair (y)) >> { >> if (scm_is_false (scm_equal_p (SCM_CAR (x), SCM_CAR (y)))) >> > > Yes, that looks reasonable. scm_is_symbol checks some tag subset that > the code for equal_p later looks at closer as well: if you worry about > the extra cost of the scm_is_symbol check, one could try folding the > symbol check into that later code passage, which would slow down the > symbol check and effect the more costly fallbacks less. But since those > fallbacks _are_ more costly, I doubt it would be worth the trouble. Looking at eq.c, I don’t see what “costly fallbacks” you’re referring to. For a symbol, AIUI, we end up here: switch (SCM_TYP7 (x)) { default: /* Check equality between structs of equal type (see cell-type test above). */ if (SCM_STRUCTP (x)) { if (SCM_INSTANCEP (x)) goto generic_equal; else return scm_i_struct_equalp (x, y); } break; // <- here, meaning we return SCM_BOOL_F All the checks leading to this line are type tag comparisons. Am I overlooking something? Thanks, Ludo’.