Le lun. 21 sept. 2020 à 21:46, Antoine Pitrou <solip...@pitrou.net> 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 -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/GQQ56I236ZUU3WOR5PS6N5WIEWNNOD47/ Code of Conduct: http://python.org/psf/codeofconduct/