Skip to content

Commit 19f426c

Browse files
committed
performance: first special cases, than all others (otherwise tuple will be traversed twice)
1 parent 198f9ba commit 19f426c

File tree

1 file changed

+20
-11
lines changed

1 file changed

+20
-11
lines changed

pandas/_libs/src/klib/khash_python.h

+20-11
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,12 @@ KHASH_MAP_INIT_COMPLEX128(complex128, size_t)
164164

165165

166166
int PANDAS_INLINE floatobject_cmp(PyFloatObject* a, PyFloatObject* b){
167-
return Py_IS_NAN(PyFloat_AS_DOUBLE(a)) &&
168-
Py_IS_NAN(PyFloat_AS_DOUBLE(b));
167+
return (
168+
Py_IS_NAN(PyFloat_AS_DOUBLE(a)) &&
169+
Py_IS_NAN(PyFloat_AS_DOUBLE(b))
170+
)
171+
||
172+
( PyFloat_AS_DOUBLE(a) == PyFloat_AS_DOUBLE(b) );
169173
}
170174

171175

@@ -187,6 +191,11 @@ int PANDAS_INLINE complexobject_cmp(PyComplexObject* a, PyComplexObject* b){
187191
a->cval.real == b->cval.real &&
188192
Py_IS_NAN(a->cval.imag) &&
189193
Py_IS_NAN(b->cval.imag)
194+
)
195+
||
196+
(
197+
a->cval.real == b->cval.real &&
198+
a->cval.imag == b->cval.imag
190199
);
191200
}
192201

@@ -210,15 +219,8 @@ int PANDAS_INLINE tupleobject_cmp(PyTupleObject* a, PyTupleObject* b){
210219

211220

212221
int PANDAS_INLINE pyobject_cmp(PyObject* a, PyObject* b) {
213-
int result = PyObject_RichCompareBool(a, b, Py_EQ);
214-
if (result < 0) {
215-
PyErr_Clear();
216-
return 0;
217-
}
218-
if (result == 0) { // still could be built-ins with NaNs
219-
if (Py_TYPE(a) != Py_TYPE(b)) {
220-
return 0;
221-
}
222+
if (Py_TYPE(a) == Py_TYPE(b)) {
223+
// special handling for some built-in types which could have NaNs:
222224
if (PyFloat_CheckExact(a)) {
223225
return floatobject_cmp((PyFloatObject*)a, (PyFloatObject*)b);
224226
}
@@ -228,7 +230,14 @@ int PANDAS_INLINE pyobject_cmp(PyObject* a, PyObject* b) {
228230
if (PyTuple_CheckExact(a)) {
229231
return tupleobject_cmp((PyTupleObject*)a, (PyTupleObject*)b);
230232
}
233+
// frozenset isn't yet supported
231234
}
235+
236+
int result = PyObject_RichCompareBool(a, b, Py_EQ);
237+
if (result < 0) {
238+
PyErr_Clear();
239+
return 0;
240+
}
232241
return result;
233242
}
234243

0 commit comments

Comments
 (0)