[Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.85,2.86

Tim Peters tim_one@users.sourceforge.net
Thu, 10 May 2001 14:45:21 -0700


Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv31424/python/dist/src/Objects

Modified Files:
	dictobject.c 
Log Message:
Restore dicts' tp_compare slot, and change dict_richcompare to say it
doesn't know how to do LE, LT, GE, GT.  dict_richcompare can't do the
latter any faster than dict_compare can.  More importantly, for
cmp(dict1, dict2), Python *first* tries rich compares with EQ, LT, and
GT one at a time, even if the tp_compare slot is defined, and
dict_richcompare called dict_compare for the latter two because
it couldn't do them itself.  The result was a lot of wasted calls to
dict_compare.  Now dict_richcompare gives up at once the times Python
calls it with LT and GT from try_rich_to_3way_compare(), and dict_compare
is called only once (when Python gets around to trying the tp_compare
slot).
Continued mystery:  despite that this cut the number of calls to
dict_compare approximately in half in test_mutants.py, the latter still
runs amazingly slowly.  Running under the debugger doesn't show excessive
activity in the dict comparison code anymore, so I'm guessing the culprit
is somewhere else -- but where?  Perhaps in the element (key/value)
comparison code?  We clearly spend a lot of time figuring out how to
compare things.


Index: dictobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v
retrieving revision 2.85
retrieving revision 2.86
diff -C2 -r2.85 -r2.86
*** dictobject.c	2001/05/10 18:58:31	2.85
--- dictobject.c	2001/05/10 21:45:19	2.86
***************
*** 1161,1178 ****
  		res = (cmp == (op == Py_EQ)) ? Py_True : Py_False;
  	}
! 	else {
! 		cmp = dict_compare((dictobject *)v, (dictobject *)w);
! 		if (cmp < 0 && PyErr_Occurred())
! 			return NULL;
! 		switch (op) {
! 			case Py_LT: cmp = cmp <  0; break;
! 			case Py_LE: cmp = cmp <= 0; break;
! 			case Py_GT: cmp = cmp >  0; break;
! 			case Py_GE: cmp = cmp >= 0; break;
! 			default:
! 				assert(!"op unexpected");
! 		}
! 		res = cmp ? Py_True : Py_False;
! 	}
  	Py_INCREF(res);
  	return res;
--- 1161,1166 ----
  		res = (cmp == (op == Py_EQ)) ? Py_True : Py_False;
  	}
! 	else
! 		res = Py_NotImplemented;
  	Py_INCREF(res);
  	return res;
***************
*** 1542,1546 ****
  	(getattrfunc)dict_getattr,		/* tp_getattr */
  	0,					/* tp_setattr */
! 	0,					/* tp_compare */
  	(reprfunc)dict_repr,			/* tp_repr */
  	0,					/* tp_as_number */
--- 1530,1534 ----
  	(getattrfunc)dict_getattr,		/* tp_getattr */
  	0,					/* tp_setattr */
! 	(cmpfunc)dict_compare,			/* tp_compare */
  	(reprfunc)dict_repr,			/* tp_repr */
  	0,					/* tp_as_number */