pochmann
(Stefan Pochmann)
July 15, 2023, 3:17pm
1
I just saw this new issue:
opened 04:51AM - 15 Jul 23 UTC
type-feature
performance
3.13
This will improve the performance of `list(d.values())` for example.
I was under the impression that list(...)
already used __len__
as well and that dict and dict views already offer that. Where am I mistaken? How would adding __length_hint__
help there?
I think list(iterable)
uses list_extend
to get the elements into the list:
assert(0 <= Py_SIZE(self));
assert(Py_SIZE(self) <= self->allocated || self->allocated == -1);
assert(self->ob_item != NULL ||
self->allocated == 0 || self->allocated == -1);
/* Empty previous contents */
if (self->ob_item != NULL) {
(void)_list_clear(self);
}
if (iterable != NULL) {
PyObject *rv = list_extend(self, iterable);
if (rv == NULL)
return -1;
Py_DECREF(rv);
}
return 0;
}
static PyObject *
list_vectorcall(PyObject *type, PyObject * const*args,
size_t nargsf, PyObject *kwnames)
And list_extend
uses PyObject_LengthHint
:
Py_DECREF(iterable);
Py_RETURN_NONE;
}
it = PyObject_GetIter(iterable);
if (it == NULL)
return NULL;
iternext = *Py_TYPE(it)->tp_iternext;
/* Guess a result list size. */
n = PyObject_LengthHint(iterable, 8);
if (n < 0) {
Py_DECREF(it);
return NULL;
}
m = Py_SIZE(self);
if (m > PY_SSIZE_T_MAX - n) {
/* m + n overflowed; on the chance that n lied, and there really
* is enough room, ignore it. If n was telling the truth, we'll
* eventually run out of memory during the loop.
*/
And PyObject_LengthHint
already tries __len__
first:
/* The length hint function returns a non-negative value from o.__len__()
or o.__length_hint__(). If those methods aren't found the defaultvalue is
returned. If one of the calls fails with an exception other than TypeError
this function returns -1.
*/
Py_ssize_t
PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)
{
PyObject *hint, *result;
Py_ssize_t res;
if (_PyObject_HasLen(o)) {
res = PyObject_Length(o);
if (res < 0) {
PyThreadState *tstate = _PyThreadState_GET();
assert(_PyErr_Occurred(tstate));
if (!_PyErr_ExceptionMatches(tstate, PyExc_TypeError)) {
return -1;
}
_PyErr_Clear(tstate);
This file has been truncated. show original
I wonder if this was overlooked or seen as not important.
If almost all use is as an iterator then its not needed.
tjreedy
(Terry Jan Reedy)
July 15, 2023, 6:39pm
3
I posted a link to this question on the issue.
tjreedy
(Terry Jan Reedy)
July 15, 2023, 7:56pm
4
Raymond closed the issue.
1 Like
pochmann
(Stefan Pochmann)
July 15, 2023, 11:46pm
5
Ok, thanks. I just felt it was way more likely that I was missing something, so I didn’t want to bother him there.