@@ -1226,13 +1226,6 @@ struct s_MergeState {
1226
1226
* of tuples. It may be set to safe_object_compare, but the idea is that hopefully
1227
1227
* we can assume more, and use one of the special-case compares. */
1228
1228
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 ;
1236
1229
};
1237
1230
1238
1231
/* binarysort is the best method for sorting small arrays: it does
@@ -2205,24 +2198,7 @@ unsafe_float_compare(PyObject *v, PyObject *w, MergeState *ms)
2205
2198
* using the same pre-sort check as we use for ms->key_compare,
2206
2199
* but run on the list [x[0] for x in L]. This allows us to optimize compares
2207
2200
* 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:]. */
2226
2202
static int
2227
2203
unsafe_tuple_compare (PyObject * v , PyObject * w , MergeState * ms )
2228
2204
{
@@ -2238,52 +2214,26 @@ unsafe_tuple_compare(PyObject *v, PyObject *w, MergeState *ms)
2238
2214
2239
2215
vt = (PyTupleObject * )v ;
2240
2216
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 );
2264
2217
2265
2218
vlen = Py_SIZE (vt );
2266
2219
wlen = Py_SIZE (wt );
2267
- for (; i < vlen && i < wlen ; i ++ ) {
2220
+
2221
+ for (i = 0 ; i < vlen && i < wlen ; i ++ ) {
2268
2222
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
- }
2280
2223
if (k < 0 )
2281
2224
return -1 ;
2225
+ if (!k )
2226
+ break ;
2282
2227
}
2283
- /* all equal until we fell off the end */
2284
- return vlen < wlen ;
2285
2228
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
+ }
2287
2237
2288
2238
/* An adaptive, stable, natural mergesort. See listsort.txt.
2289
2239
* 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)
2466
2416
}
2467
2417
2468
2418
ms .key_compare = unsafe_tuple_compare ;
2469
- ms .first_tuple_items_resolved_it = 1 ; /* be optimistic */
2470
2419
}
2471
2420
}
2472
2421
/* End of pre-sort check: ms is now set properly! */
0 commit comments