[Python-Dev] Comparison speed

Michael Hudson mwh@python.net
20 May 2001 12:52:40 +0100


"Tim Peters" <tim.one@home.com> writes:

> Ah!  Of course.  string_compare is hardwired into lookdict_string.
> This case may be important enough to merit a distinct
> _PyString_Equal function, with just the stuff lookdict_string needs

Or just inlining it all into lookdict_string, something like:

Index: Objects/dictobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v
retrieving revision 2.90
diff -c -r2.90 dictobject.c
*** Objects/dictobject.c	2001/05/19 07:04:38	2.90
--- Objects/dictobject.c	2001/05/20 11:51:28
***************
*** 279,286 ****
  	register unsigned int mask = mp->ma_size-1;
  	dictentry *ep0 = mp->ma_table;
  	register dictentry *ep;
- 	cmpfunc compare = PyString_Type.tp_compare;
  
  	/* make sure this function doesn't have to handle non-string keys */
  	if (!PyString_Check(key)) {
  #ifdef SHOW_CONVERSION_COUNTS
--- 279,287 ----
  	register unsigned int mask = mp->ma_size-1;
  	dictentry *ep0 = mp->ma_table;
  	register dictentry *ep;
  
+ #define S(s) ((PyStringObject*)(s))
+ 
  	/* make sure this function doesn't have to handle non-string keys */
  	if (!PyString_Check(key)) {
  #ifdef SHOW_CONVERSION_COUNTS
***************
*** 299,305 ****
  		freeslot = ep;
  	else {
  		if (ep->me_hash == hash
! 		    && compare(ep->me_key, key) == 0) {
  			return ep;
  		}
  		freeslot = NULL;
--- 300,308 ----
  		freeslot = ep;
  	else {
  		if (ep->me_hash == hash
! 		    && S(ep->me_key)->ob_size == S(key)->ob_size
! 		    && memcmp(S(ep->me_key)->ob_sval,
! 			      S(key)->ob_sval,S(key)->ob_size) == 0) {
  			return ep;
  		}
  		freeslot = NULL;
***************
*** 318,324 ****
  		if (ep->me_key == key
  		    || (ep->me_hash == hash
  		        && ep->me_key != dummy
! 			&& compare(ep->me_key, key) == 0))
  			return ep;
  		else if (ep->me_key == dummy && freeslot == NULL)
  			freeslot = ep;
--- 321,329 ----
  		if (ep->me_key == key
  		    || (ep->me_hash == hash
  		        && ep->me_key != dummy
! 			&& S(ep->me_key)->ob_size == S(key)->ob_size
! 			&& memcmp(S(ep->me_key)->ob_sval,
! 				  S(key)->ob_sval,S(key)->ob_size) == 0))
  			return ep;
  		else if (ep->me_key == dummy && freeslot == NULL)
  			freeslot = ep;
***************
*** 327,332 ****
--- 332,339 ----
  		if (incr > mask)
  			incr ^= mp->ma_poly; /* clears the highest bit */
  	}
+ 
+ #undef S
  }
  
  /*

(apologies for the use of the preprocessor...).  I'll leave it to
someone else to work out if this is a win or not...

-- 
                    >> REVIEW OF THE YEAR, 2000 <<
                   It was shit. Give us another one.
                          -- NTK Know, 2000-12-29, http://www.ntk.net/