Le lun. 21 sept. 2020 à 21:46, Antoine Pitrou <[email protected]> a écrit :
> > The main benefit is the memory usage. For example, list(range(200))
> > uses 1656 bytes instead of 7262 (4x less memory).
>
> Hmm, how come? Aren't those tiny integers singletons already?
These numbers come from the code:
import sys
def size(l):
return sys.getsizeof(l) + sum(sys.getsizeof(item) for item in l)
print(size(list(range(200))), "bytes")
The code doesn't ignore the object size of singletons but count their
memory as if they are allocated on the heap memory.
It took a shortcut: I counted as if my implementation would support
any number, and not only existing Python singletons.
On my current implementation, list(range(200))) doesn't use more or
less memory, but the same amount.
> > Sadly, my current simple implementation is 1.1x slower than the
> > reference. I suspect that adding a condition to Py_INCREF() and
> > Py_DECREF() explains a large part of this overhead.
>
> And adding a condition in every place an object is inspected. Even
> something as simple as Py_TYPE() is not a mere lookup anymore.
You're right that Py_TYPE() also gets a condition to check if the
pointer is tagged:
https://github.com/vstinner/cpython/blob/tagged_ptr/Include/object.h#L203
By the way, Py_INCREF() and Py_DECREF() use:
if (_Py_TAGPTR_IS_TAGGED(op)) {
// Tagged pointers are immutable
return;
}
https://github.com/vstinner/cpython/blob/tagged_ptr/Include/object.h#L497
> > It would be nice to use tagged pointers for a wide range of integer
> > numbers, but I wrote a simple implementation: _Py_TAGPTR_UNBOX() has
> > to return a borrowed reference. This function should return a strong
> > reference to support a larger range.
>
> Hmm, it sounds a bit weird. The point of tagged pointers, normally, is
> to avoid creating objects at all. If you create an object dynamically
> each time a tagged pointer is "dereferenced", then I suspect you won't
> gain anything.
Sure, functions could be optimized to avoid the creation of temporary
objects. I wrote a simple implementation which leaves the code as it
is, but "unbox" tagged pointers when a function access directly object
members. Example in listobject.c:
vl = (PyLongObject*)_Py_TAGPTR_UNBOX(v);
wl = (PyLongObject*)_Py_TAGPTR_UNBOX(w);
v0 = Py_SIZE(vl) == 0 ? 0 : (sdigit)vl->ob_digit[0];
w0 = Py_SIZE(wl) == 0 ? 0 : (sdigit)wl->ob_digit[0];
"vl->ob_digit" crashes if vl is a tagged pointer.
My first goal was to write a *correct* (working) implementation, not
really an optimized implementation.
That's why I'm calling for help to attempt to optimize it ;-)
Victor
--
Night gathers, and now my watch begins. It shall not end until my death.
_______________________________________________
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/GQQ56I236ZUU3WOR5PS6N5WIEWNNOD47/
Code of Conduct: http://python.org/psf/codeofconduct/