@@ -1226,13 +1226,6 @@ struct s_MergeState {
12261226 * of tuples. It may be set to safe_object_compare, but the idea is that hopefully
12271227 * we can assume more, and use one of the special-case compares. */
12281228 int (* tuple_elem_compare )(PyObject * , PyObject * , MergeState * );
1229-
1230- /* Used by unsafe_tuple_compare to record whether the very first tuple
1231- * elements resolved the last comparison attempt. If so, next time a
1232- * method that may avoid PyObject_RichCompareBool() entirely is tried.
1233- * 0 for false, 1 for true.
1234- */
1235- int first_tuple_items_resolved_it ;
12361229};
12371230
12381231/* binarysort is the best method for sorting small arrays: it does
@@ -2205,24 +2198,7 @@ unsafe_float_compare(PyObject *v, PyObject *w, MergeState *ms)
22052198 * using the same pre-sort check as we use for ms->key_compare,
22062199 * but run on the list [x[0] for x in L]. This allows us to optimize compares
22072200 * on two levels (as long as [x[0] for x in L] is type-homogeneous.) The idea is
2208- * that most tuple compares don't involve x[1:].
2209- * However, that may not be right. When it is right, we can win by calling the
2210- * relatively cheap ms->tuple_elem_compare on the first pair of elements, to
2211- * see whether v[0] < w[0] or w[0] < v[0]. If either are so, we're done.
2212- * Else we proceed as in the tuple compare, comparing the remaining pairs via
2213- * the probably more expensive PyObject_RichCompareBool(..., Py_EQ) until (if
2214- * ever) that says "no, not equal!". Then, if we're still on the first pair,
2215- * ms->tuple_elem_compare can resolve it, else PyObject_RichCompareBool(...,
2216- * Py_LT) finishes the job.
2217- * In any case, ms->first_tuple_items_resolved_it keeps track of whether the
2218- * most recent tuple comparison was resolved by the first pair. If so, the
2219- * next attempt starts by trying the cheap tests on the first pair again, else
2220- * PyObject_RichCompareBool(..., Py_EQ) is used from the start.
2221- * There are cases where PyObject_RichCompareBool(..., Py_EQ) is much cheaper!
2222- * For example, that can return "almost immediately" if passed the same
2223- * object twice (it special-cases object identity for Py_EQ), which can,
2224- * potentially, be unboundedly faster than ms->tuple_elem_compare.
2225- */
2201+ * that most tuple compares don't involve x[1:]. */
22262202static int
22272203unsafe_tuple_compare (PyObject * v , PyObject * w , MergeState * ms )
22282204{
@@ -2238,52 +2214,26 @@ unsafe_tuple_compare(PyObject *v, PyObject *w, MergeState *ms)
22382214
22392215 vt = (PyTupleObject * )v ;
22402216 wt = (PyTupleObject * )w ;
2241- i = 0 ;
2242- if (ms -> first_tuple_items_resolved_it ) {
2243- /* See whether fast compares of the first elements settle it. */
2244- k = ms -> tuple_elem_compare (vt -> ob_item [0 ], wt -> ob_item [0 ], ms );
2245- if (k ) /* error, or v < w */
2246- return k ;
2247- k = ms -> tuple_elem_compare (wt -> ob_item [0 ], vt -> ob_item [0 ], ms );
2248- if (k > 0 ) /* w < v */
2249- return 0 ;
2250- if (k < 0 ) /* error */
2251- return -1 ;
2252- /* We have
2253- * not (v[0] < w[0]) and not (w[0] < v[0])
2254- * which implies, for a total order, that the first elements are
2255- * equal. So skip them in the loop.
2256- */
2257- i = 1 ;
2258- ms -> first_tuple_items_resolved_it = 0 ;
2259- }
2260- /* Now first_tuple_items_resolved_it was 0 on entry, or was forced to 0
2261- * at the end of the `if` block just above.
2262- */
2263- assert (! ms -> first_tuple_items_resolved_it );
22642217
22652218 vlen = Py_SIZE (vt );
22662219 wlen = Py_SIZE (wt );
2267- for (; i < vlen && i < wlen ; i ++ ) {
2220+
2221+ for (i = 0 ; i < vlen && i < wlen ; i ++ ) {
22682222 k = PyObject_RichCompareBool (vt -> ob_item [i ], wt -> ob_item [i ], Py_EQ );
2269- if (!k ) { /* not equal */
2270- if (i ) {
2271- return PyObject_RichCompareBool (vt -> ob_item [i ], wt -> ob_item [i ],
2272- Py_LT );
2273- }
2274- else {
2275- ms -> first_tuple_items_resolved_it = 1 ;
2276- return ms -> tuple_elem_compare (vt -> ob_item [0 ], wt -> ob_item [0 ],
2277- ms );
2278- }
2279- }
22802223 if (k < 0 )
22812224 return -1 ;
2225+ if (!k )
2226+ break ;
22822227 }
2283- /* all equal until we fell off the end */
2284- return vlen < wlen ;
22852228
2286- }
2229+ if (i >= vlen || i >= wlen )
2230+ return vlen < wlen ;
2231+
2232+ if (i == 0 )
2233+ return ms -> tuple_elem_compare (vt -> ob_item [i ], wt -> ob_item [i ], ms );
2234+ else
2235+ return PyObject_RichCompareBool (vt -> ob_item [i ], wt -> ob_item [i ], Py_LT );
2236+ }
22872237
22882238/* An adaptive, stable, natural mergesort. See listsort.txt.
22892239 * Returns Py_None on success, NULL on error. Even in case of error, the
@@ -2466,7 +2416,6 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse)
24662416 }
24672417
24682418 ms .key_compare = unsafe_tuple_compare ;
2469- ms .first_tuple_items_resolved_it = 1 ; /* be optimistic */
24702419 }
24712420 }
24722421 /* End of pre-sort check: ms is now set properly! */
0 commit comments