Message242085
| Author |
rhettinger |
| Recipients |
barry, eric.smith, eric.snow, llllllllll, rhettinger |
| Date |
2015年04月26日.23:04:43 |
| SpamBayes Score |
-1.0 |
| Marked as misclassified |
Yes |
| Message-id |
<1430089483.51.0.982412630927.issue23910@psf.upfronthosting.co.za> |
| In-reply-to |
| Content |
One other thought: the itemgetter.__call__ method is already pretty thin:
if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &obj))
return NULL;
if (nitems == 1)
return PyObject_GetItem(obj, ig->item);
But you could add a special case for single integer index being applied to a known sequence. Extract the Py_ssize_t index in itemgetter_new and store it in the itemgetterobject. Then add a fast path in itemgetter.__call__. Roughly something like this:
if (ig->index != -1 &&
PyTuple_Check(obj) &&
nitems == 1 &&
PyTuple_GET_SIZE(obj) > ig->index) {
result = PySequence_Fast_GET_ITEM(obj, ig->index);
Py_INCREF(result);
return result;
}
Perhaps also add a check to make sure the tuple subclass hasn't overridden the __getitem__ method (see an example of how to do this in the code for Modules/_collectionsmodule.c::_count_elements()).
Something along these lines would allow all the steps to be inlined and would eliminate all the usual indirections inherent in the abstract API.
Another alternative is to use the PySequence API instead of the PyTuple API. That trades away a little of the speed-up in return for speeding-up itemgetter on lists as well as tuples. |
|
History
|
|---|
| Date |
User |
Action |
Args |
| 2015年04月26日 23:04:43 | rhettinger | set | recipients:
+ rhettinger, barry, eric.smith, eric.snow, llllllllll |
| 2015年04月26日 23:04:43 | rhettinger | set | messageid: <1430089483.51.0.982412630927.issue23910@psf.upfronthosting.co.za> |
| 2015年04月26日 23:04:43 | rhettinger | link | issue23910 messages |
| 2015年04月26日 23:04:43 | rhettinger | create |
|