Subject: subtract_array() From: Michael Sporn <sporn@mathematik.hu-berlin.de> Date: Tue, 16 Mar 1999 17:19:59 +0100 (MET) Type: Patch State: Done - applied in 3.2-dev.56 Hallo Lars, ich hab mir meine subtract_array() - optimierung noch mal angeschaut und noch eine Verbesserung eingebaut: Fuer Subtrahenden der Groesse 1 wird jetzt auch das assoc() vermieden, was die Geschwindigkeit bei string-arrays nochmal auf mehr als das Dreifache, bei normalen arrays auf das Doppelte steigen laesst. Ciao, Michael -- Michael Sporn <sporn@mathematik.hu-berlin.de> --- ldmud-dev48/array.c Sat Mar 6 01:01:43 1999 +++ ldmud-dev/array.c Tue Mar 16 16:53:35 1999 @@ -704,33 +704,30 @@ } /*-------------------------------------------------------------------------*/ -static INLINE void -alist_canonify (struct svalue *svp) -/* Bring <svp> into the format expected/created by order_alist: unshared - * strings are made shared, destructed objects are replaced by svalue-0. - * <*svp> is modified in-place. - */ +static int +compare_aux (struct svalue *p1, struct vector *v) + +/* + * compare *p1 and v->item[0], return 0 if equal, else -1 + */ { - if (svp->type == T_STRING) - { - if (svp->x.string_type != STRING_SHARED) - { - char *str = make_shared_string(svp->u.string); - free_string_svalue(svp); - svp->x.string_type = STRING_SHARED; - svp->u.string = str; - } - } - else if (svp->type == T_OBJECT) - { - if (svp->u.ob->flags & O_DESTRUCTED) - { - free_object_svalue(svp); - svp->type = T_NUMBER; - svp->u.number = 0; - } + struct svalue *p2 = &v->item[0]; + + if (p1->type != p2->type) return -1; + if (p1->type == T_STRING) + return strcmp(p1->u.string, p2->u.string) ? -1 : 0; + + if (p1->u.number != p2->u.number) return -1; + switch (p1->type) { + case T_FLOAT: + case T_CLOSURE: + case T_SYMBOL: + case T_QUOTED_ARRAY: + return p1->x.generic != p2->x.generic ? -1 : 0; + default: + return 0; } } @@ -758,6 +755,10 @@ struct vector *vtmpp; /* {( Ordered <subtrahend> }) */ struct svalue *source, *dest; /* Pointers into minuend and difference vector */ + + /* function used to find an svalue in a (sorted) vector */ + int (*assoc_function) (struct svalue*, struct vector*); + mp_int i; mp_int minuend_size = VEC_SIZE(minuend); mp_int subtrahend_size = VEC_SIZE(subtrahend); @@ -778,7 +779,12 @@ /* Order the subtrahend */ if (subtrahend_size == 1) { - alist_canonify( &subtrahend->item[0] ); + if (subtrahend->item[0].type == T_OBJECT + && subtrahend->item[0].u.ob->flags & O_DESTRUCTED) + { + assign_svalue(&subtrahend->item[0], &const0); + } + assoc_function = &compare_aux; vtmpp = subtrahend; } else @@ -786,6 +792,7 @@ ltmp.u.vec = subtrahend; vtmpp = order_alist(<mp, 1, 1); free_vector(ltmp.u.vec); + assoc_function = &assoc; subtrahend = vtmpp->item[0].u.vec; } @@ -800,13 +807,13 @@ { if (source->type == T_OBJECT && source->u.ob->flags & O_DESTRUCTED) assign_svalue(source, &const0); - if ( assoc(source, subtrahend) >-1 ) break; + if ( (*assoc_function)(source, subtrahend) >-1 ) break; } for (dest = source++; i-->0 ; source++) { if (source->type == T_OBJECT && source->u.ob->flags & O_DESTRUCTED) assign_svalue(source, &const0); - if ( assoc(source, subtrahend) < 0 ) + if ( (*assoc_function)(source, subtrahend) < 0 ) assign_svalue(dest++, source); } free_vector(vtmpp); @@ -821,7 +828,7 @@ ; source++) { if (source->type == T_OBJECT && source->u.ob->flags & O_DESTRUCTED) assign_svalue(source, &const0); - if ( assoc(source, subtrahend) < 0 ) + if ( (*assoc_function)(source, subtrahend) < 0 ) assign_svalue_no_free(dest++, source); }