Can you please explain why this happens in Python v3.8?
a=round(2.3)
b=round(2.4)
print(a,b)
print(type(a),type(b))
print(a is b)
print(id(a))
print(id(b))
Output:
2 2
<class 'int'> <class 'int'>
False
2406701496848
2406701496656
>>>
2 is within the range of the small integer caching. So why are there different objects with the same value?
Python caches small integers, which are integers between -5 and 256 .
Java Integer Cache Implementation:Integer objects are cached internally and reused via the same referenced objects. This is applicable for Integer values in the range between –128 to +127. This Integer caching works only on auto-boxing. Integer objects will not be cached when they are built using the constructor.
We have established that Python indeed is consuming smaller integers through their corresponding singleton instances, without reallocating them every time. Now we verify the hypothesis that Python indeed saves a bunch of allocations during its initialization through these singletons.
Looks like in 3.8, PyLong_FromDouble
(which is what float.__round__
ultimately delegates to) explicitly allocates a new PyLong
object and fills it in manually, without normalizing it (via the IS_SMALL_INT
check and get_small_int
cache lookup function), so it doesn't check the small int
cache to resolve to the canonical value.
This will change in 3.9 as a result of issue 37986: Improve perfomance of PyLong_FromDouble(), which now has it delegate to PyLong_FromLong
when the double
is small enough to be losslessly represented as a C long
. By side-effect, this will use the small int
cache, as PyLong_FromLong
reliably normalizes for small values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With