[Python-Dev] Comparison speed
Martin v. Loewis
martin@loewis.home.cs.tu-berlin.de
Mon, 14 May 2001 23:55:39 +0200
> Anybody care to take a stab at making the new richcmp and/or coerce
> code ugly again?
Hi Tim,
With CVS Python, 1000000 iterations, and a for loop, I currently got
0.780
0.770
0.770
0.780
0.770
0.770
0.770
0.780
0.770
0.770
With the patch below, I get
0.720
0.710
0.710
0.720
0.710
0.710
0.710
0.720
0.710
0.710
The idea is to let strings support richcmp; this also allows some
optimization for the EQ case.
Please let me know what you think.
Martin
Index: stringobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v
retrieving revision 2.115
diff -u -r2.115 stringobject.c
--- stringobject.c 2001/05/10 00:32:57 2.115
+++ stringobject.c 2001/05/14 21:36:36
@@ -596,6 +596,51 @@
return (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0;
}
+/* In the signature, only a is guaranteed to be a PyStringObject.
+ However, as the first thing in the function, we check that b
+ is of that type also. */
+
+static PyObject*
+string_richcompare(PyStringObject *a, PyStringObject *b, int op)
+{
+ int c;
+ PyObject *result;
+ if (!PyString_Check(b)) {
+ result = Py_NotImplemented;
+ goto out;
+ }
+ if (op == Py_EQ) {
+ if (a->ob_size != b->ob_size) {
+ result = Py_False;
+ goto out;
+ }
+#ifdef CACHE_HASH
+ if (a->ob_shash != b->ob_shash
+ && a->ob_shash != -1
+ && b->ob_shash != -1) {
+ result = Py_False;
+ goto out;
+ }
+#endif
+ }
+ c = string_compare(a, b);
+ switch (op) {
+ case Py_LT: c = c < 0; break;
+ case Py_LE: c = c <= 0; break;
+ case Py_EQ: c = c == 0; break;
+ case Py_NE: c = c != 0; break;
+ case Py_GT: c = c > 0; break;
+ case Py_GE: c = c >= 0; break;
+ default:
+ result = Py_NotImplemented;
+ goto out;
+ }
+ result = c ? Py_True : Py_False;
+ out:
+ Py_INCREF(result);
+ return result;
+}
+
static long
string_hash(PyStringObject *a)
{
@@ -2409,6 +2454,12 @@
&string_as_buffer, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ (richcmpfunc)string_richcompare, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
};
void