-
-
Notifications
You must be signed in to change notification settings - Fork 34.5k
bpo-28685: Optimize sorted() list.sort() with type-specialized comparisons #582
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
89c278f
2ce5e5e
7d2f44a
d752fc7
e19728e
7e74c27
9c566b1
8876e26
8accd71
1567801
3820cdb
201a468
c2a9df2
37b15b8
e402948
ed9b21f
acf4c9d
395bc7d
e677586
6070c72
294aa1c
ba05b2a
40ba266
a175939
f0dc847
15f87a2
15f2f01
6afa847
af7c027
20716cb
5960fbe
804807b
5db7158
934d83f
c536ed3
0b85ac5
a12d784
a54a4e4
20172fb
862c761
dd302b5
ab3d520
dba3f27
c796422
fa19903
014fd8f
e4679e2
3b3ce52
afed812
ebb4c1f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1942,18 +1942,20 @@ safe_object_compare(PyObject* v, PyObject* w, MergeState* ms) | |
| static int | ||
| unsafe_object_compare(PyObject* v, PyObject* w, MergeState* ms) | ||
| { | ||
| /* Modified from Objects/object.c:PyObject_RichCompareBool, assuming: */ | ||
| #ifdef Py_DEBUG | ||
| assert(v->ob_type == w->ob_type && | ||
| v->ob_type->tp_richcompare != NULL); | ||
| #endif | ||
| int ok; | ||
| int ok; PyObject* res; | ||
|
|
||
| /* Modified from Objects/object.c:PyObject_RichCompareBool, assuming: */ | ||
| #ifdef Py_DEBUG | ||
| assert(v->ob_type == w->ob_type && | ||
| v->ob_type->tp_richcompare != NULL); | ||
| #endif | ||
|
|
||
|
|
||
| if (v == w) return 0; | ||
| if (v->ob_type->tp_richcompare != ms->key_richcompare) | ||
| return PyObject_RichCompareBool(v, w, Py_LT); | ||
|
|
||
| PyObject* res = (*(ms->key_richcompare))(v, w, Py_LT); | ||
| res = (*(ms->key_richcompare))(v, w, Py_LT); | ||
|
|
||
| if (res == Py_NotImplemented) { | ||
| Py_DECREF(res); | ||
|
|
@@ -1975,16 +1977,18 @@ unsafe_object_compare(PyObject* v, PyObject* w, MergeState* ms) | |
| /* Latin string compare: safe for any two latin (one byte per char) strings. */ | ||
| static int | ||
| unsafe_latin_compare(PyObject* v, PyObject* w, MergeState* ms){ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move |
||
| /* Modified from Objects/unicodeobject.c:unicode_compare, assuming: */ | ||
| #ifdef Py_DEBUG | ||
| assert(v->ob_type == w->ob_type && | ||
| v->ob_type == &PyUnicode_Type && | ||
| PyUnicode_KIND(v) == PyUnicode_KIND(w) && | ||
| PyUnicode_KIND(v) == PyUnicode_1BYTE_KIND); | ||
| #endif | ||
| int len, res; | ||
|
|
||
| /* Modified from Objects/unicodeobject.c:unicode_compare, assuming: */ | ||
| #ifdef Py_DEBUG | ||
| assert(v->ob_type == w->ob_type && | ||
| v->ob_type == &PyUnicode_Type && | ||
| PyUnicode_KIND(v) == PyUnicode_KIND(w) && | ||
| PyUnicode_KIND(v) == PyUnicode_1BYTE_KIND); | ||
| #endif | ||
|
|
||
| int len = Py_MIN(PyUnicode_GET_LENGTH(v), PyUnicode_GET_LENGTH(w)); | ||
| int res = memcmp(PyUnicode_DATA(v), PyUnicode_DATA(w), len); | ||
| len = Py_MIN(PyUnicode_GET_LENGTH(v), PyUnicode_GET_LENGTH(w)); | ||
| res = memcmp(PyUnicode_DATA(v), PyUnicode_DATA(w), len); | ||
|
|
||
| return (res != 0 ? | ||
| res < 0 : | ||
|
|
@@ -1995,20 +1999,21 @@ unsafe_latin_compare(PyObject* v, PyObject* w, MergeState* ms){ | |
| static int | ||
| unsafe_long_compare(PyObject *v, PyObject *w, MergeState* ms) | ||
| { | ||
| /* Modified from Objects/longobject.c:long_compare, assuming: */ | ||
| #ifdef Py_DEBUG | ||
| assert(v->ob_type == w->ob_type && | ||
| v->ob_type == &PyLong_Type && | ||
| Py_ABS(Py_SIZE(v)) <= 1 && | ||
| Py_ABS(Py_SIZE(w)) <= 1); | ||
| #endif | ||
| PyLongObject *vl, *wl; sdigit v0, w0; | ||
|
|
||
| /* Modified from Objects/longobject.c:long_compare, assuming: */ | ||
| #ifdef Py_DEBUG | ||
| assert(v->ob_type == w->ob_type && | ||
| v->ob_type == &PyLong_Type && | ||
| Py_ABS(Py_SIZE(v)) <= 1 && | ||
| Py_ABS(Py_SIZE(w)) <= 1); | ||
| #endif | ||
|
|
||
| PyLongObject *vl, *wl; | ||
| vl = (PyLongObject*)v; | ||
| wl = (PyLongObject*)w; | ||
|
|
||
| sdigit v0 = Py_SIZE(vl) == 0 ? 0 : (sdigit)vl->ob_digit[0]; | ||
| sdigit w0 = Py_SIZE(wl) == 0 ? 0 : (sdigit)wl->ob_digit[0]; | ||
| v0 = Py_SIZE(vl) == 0 ? 0 : (sdigit)vl->ob_digit[0]; | ||
| w0 = Py_SIZE(wl) == 0 ? 0 : (sdigit)wl->ob_digit[0]; | ||
|
|
||
| if (Py_SIZE(vl) < 0) | ||
| v0 = -v0; | ||
|
|
@@ -2021,13 +2026,13 @@ unsafe_long_compare(PyObject *v, PyObject *w, MergeState* ms) | |
| /* Float compare: compare any two floats. */ | ||
| static int | ||
| unsafe_float_compare(PyObject *v, PyObject *w, MergeState* ms){ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move |
||
| /* Modified from Objects/floatobject.c:float_richcompare, assuming: */ | ||
| #ifdef Py_DEBUG | ||
| assert(v->ob_type == w->ob_type && | ||
| v->ob_type == &PyFloat_Type); | ||
| #endif | ||
| if (v == w) return 0; | ||
|
|
||
| /* Modified from Objects/floatobject.c:float_richcompare, assuming: */ | ||
| #ifdef Py_DEBUG | ||
| assert(v->ob_type == w->ob_type && | ||
| v->ob_type == &PyFloat_Type); | ||
| #endif | ||
| if (v == w) return 0; | ||
| return PyFloat_AS_DOUBLE(v) < PyFloat_AS_DOUBLE(w); | ||
| } | ||
|
|
||
|
|
@@ -2038,25 +2043,23 @@ unsafe_float_compare(PyObject *v, PyObject *w, MergeState* ms){ | |
| * on two levels (as long as [x[0] for x in L] is type-homogeneous.) */ | ||
| static int | ||
| unsafe_tuple_compare(PyObject* v, PyObject* w, MergeState* ms) | ||
| { | ||
| /* Modified from Objects/tupleobject.c:tuplerichcompare, assuming: */ | ||
| #ifdef Py_DEBUG | ||
| assert(v->ob_type == w->ob_type && | ||
| v->ob_type == &PyTuple_Type && | ||
| Py_SIZE(v) > 0 && | ||
| Py_SIZE(w) > 0); | ||
| #endif | ||
|
|
||
| { | ||
| PyTupleObject *vt, *wt; | ||
| Py_ssize_t i; | ||
| Py_ssize_t vlen, wlen; | ||
| Py_ssize_t i, vlen, wlen; | ||
| int k; | ||
|
|
||
| /* Modified from Objects/tupleobject.c:tuplerichcompare, assuming: */ | ||
| #ifdef Py_DEBUG | ||
| assert(v->ob_type == w->ob_type && | ||
| v->ob_type == &PyTuple_Type && | ||
| Py_SIZE(v) > 0 && | ||
| Py_SIZE(w) > 0); | ||
| #endif | ||
|
|
||
| if (v == w) return 0; | ||
|
|
||
| vt = (PyTupleObject *)v; | ||
| wt = (PyTupleObject *)w; | ||
|
|
||
| int k; | ||
|
|
||
| if (v == w) return 0; | ||
|
|
||
| /* Is v[0] < w[0]? */ | ||
| k = (*(ms->tuple_elem_compare))(vt->ob_item[0], wt->ob_item[0], ms); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since specialized comparison is not recursive, wouldn't be safe to pass
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No. If the compare function is |
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Split the line before
return.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was actually removed -- it turns out you only need to look at addresses when you're doing equality testing.