[Python-checkins] CVS: python/dist/src/Objects object.c,2.131,2.132 typeobject.c,2.16,2.17
Martin v. L?wis
loewis@users.sourceforge.net
Sat, 09 Jun 2001 00:34:07 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv9798/Objects
Modified Files:
object.c typeobject.c
Log Message:
Patch #424475: Speed-up tp_compare usage, by special-casing the common
case of objects with equal types which support tp_compare. Give
type objects a tp_compare function.
Also add c<0 tests before a few PyErr_Occurred tests.
Index: object.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v
retrieving revision 2.131
retrieving revision 2.132
diff -C2 -r2.131 -r2.132
*** object.c 2001/05/11 03:36:45 2.131
--- object.c 2001/06/09 07:34:05 2.132
***************
*** 478,491 ****
return (*w->ob_type->tp_compare)(v, w);
- /* If the types are equal, don't bother with coercions etc. */
- if (v->ob_type == w->ob_type) {
- if ((f = v->ob_type->tp_compare) == NULL)
- return 2;
- c = (*f)(v, w);
- if (PyErr_Occurred())
- return -2;
- return c < 0 ? -1 : c > 0 ? 1 : 0;
- }
-
/* Try coercion; if it fails, give up */
c = PyNumber_CoerceEx(&v, &w);
--- 478,481 ----
***************
*** 500,504 ****
Py_DECREF(v);
Py_DECREF(w);
! if (PyErr_Occurred())
return -2;
return c < 0 ? -1 : c > 0 ? 1 : 0;
--- 490,494 ----
Py_DECREF(v);
Py_DECREF(w);
! if (c < 0 && PyErr_Occurred())
return -2;
return c < 0 ? -1 : c > 0 ? 1 : 0;
***************
*** 510,514 ****
Py_DECREF(v);
Py_DECREF(w);
! if (PyErr_Occurred())
return -2;
return c < 0 ? 1 : c > 0 ? -1 : 0; /* negated! */
--- 500,504 ----
Py_DECREF(v);
Py_DECREF(w);
! if (c < 0 && PyErr_Occurred())
return -2;
return c < 0 ? 1 : c > 0 ? -1 : 0; /* negated! */
***************
*** 591,594 ****
--- 581,586 ----
0 if v == w;
1 if v > w;
+ If the object implements a tp_compare function, it returns
+ whatever this function returns (whether with an exception or not).
*/
static int
***************
*** 596,600 ****
--- 588,596 ----
{
int c;
+ cmpfunc f;
+ if (v->ob_type == w->ob_type
+ && (f = v->ob_type->tp_compare) != NULL)
+ return (*f)(v, w);
c = try_rich_to_3way_compare(v, w);
if (c < 2)
***************
*** 761,774 ****
static PyObject *
! try_3way_to_rich_compare(PyObject *v, PyObject *w, int op)
{
- int c;
PyObject *result;
-
- c = try_3way_compare(v, w);
- if (c >= 2)
- c = default_3way_compare(v, w);
- if (c <= -2)
- return NULL;
switch (op) {
case Py_LT: c = c < 0; break;
--- 757,763 ----
static PyObject *
! convert_3way_to_object(int op, int c)
{
PyObject *result;
switch (op) {
case Py_LT: c = c < 0; break;
***************
*** 783,791 ****
--- 772,820 ----
return result;
}
+
static PyObject *
+ try_3way_to_rich_compare(PyObject *v, PyObject *w, int op)
+ {
+ int c;
+
+ c = try_3way_compare(v, w);
+ if (c >= 2)
+ c = default_3way_compare(v, w);
+ if (c <= -2)
+ return NULL;
+ return convert_3way_to_object(op, c);
+ }
+
+ static PyObject *
do_richcmp(PyObject *v, PyObject *w, int op)
{
PyObject *res;
+ cmpfunc f;
+
+ /* If the types are equal, don't bother with coercions etc.
+ Instances are special-cased in try_3way_compare, since
+ a result of 2 does *not* mean one value being greater
+ than the other. */
+ if (v->ob_type == w->ob_type
+ && (f = v->ob_type->tp_compare) != NULL
+ && !PyInstance_Check(v)) {
+ int c;
+ richcmpfunc f1;
+ if ((f1 = RICHCOMPARE(v->ob_type)) != NULL) {
+ /* If the type has richcmp, try it first.
+ try_rich_compare would try it two-sided,
+ which is not needed since we've a single
+ type only. */
+ res = (*f1)(v, w, op);
+ if (res != Py_NotImplemented)
+ return res;
+ Py_DECREF(res);
+ }
+ c = (*f)(v, w);
+ if (c < 0 && PyErr_Occurred())
+ return NULL;
+ return convert_3way_to_object(op, c);
+ }
res = try_rich_compare(v, w, op);
Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.16
retrieving revision 2.17
diff -C2 -r2.16 -r2.17
*** typeobject.c 2000/09/01 23:29:27 2.16
--- typeobject.c 2001/06/09 07:34:05 2.17
***************
*** 24,27 ****
--- 24,37 ----
}
+ static int
+ type_compare(PyObject *v, PyObject *w)
+ {
+ /* This is called with type objects only. So we
+ can just compare the addresses. */
+ Py_uintptr_t vv = (Py_uintptr_t)v;
+ Py_uintptr_t ww = (Py_uintptr_t)w;
+ return (vv < ww) ? -1 : (vv > ww) ? 1 : 0;
+ }
+
static PyObject *
type_repr(PyTypeObject *v)
***************
*** 42,51 ****
(getattrfunc)type_getattr, /*tp_getattr*/
0, /*tp_setattr*/
! 0, /*tp_compare*/
(reprfunc)type_repr, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
! 0, /*tp_hash*/
0, /*tp_call*/
0, /*tp_str*/
--- 52,61 ----
(getattrfunc)type_getattr, /*tp_getattr*/
0, /*tp_setattr*/
! type_compare, /*tp_compare*/
(reprfunc)type_repr, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
! _Py_HashPointer, /*tp_hash*/
0, /*tp_call*/
0, /*tp_str*/