-
-
Notifications
You must be signed in to change notification settings - Fork 32.7k
Description
Bug report
At some lengths, calling __sizeof__() on a set gives a different value after copying said set.
The inconsistency shows up as both an increase or a decrease in reported size.
Any copying of the set results in this behavior, but modifying the set itself does not.
I've tested looking at the memory usage of a python process with regard to the created set, and it looks like the copied set has the correct __sizeof__ value.
Simple repro:
import sys
a = set(range(10_000_000))
b = a.copy()
c = set(a)
d = a.union({1})
print(a == b == c) # -> True
print(sys.getsizeof(a)) # -> 268435672
print(sys.getsizeof(b)) # -> 536871128
print(sys.getsizeof(c)) # -> 536871128
print(sys.getsizeof(d)) # -> 536871128
print(a.__sizeof__()) # -> 268435656
print(b.__sizeof__()) # -> 536871112
print(c.__sizeof__()) # -> 536871112
print(d.__sizeof__()) # -> 536871112But at other lengths, the reported size is the same.
import sys
a = set(range(10_000))
b = a.copy()
c = set(a)
print(a == b == c) # -> True
print(sys.getsizeof(a)) # -> 524504
print(sys.getsizeof(b)) # -> 524504
print(sys.getsizeof(c)) # -> 524504
print(a.__sizeof__()) # -> 524488
print(b.__sizeof__()) # -> 524488
print(c.__sizeof__()) # -> 524488I made a quick script to find the sizes this inconsistency applies to. And testing seems to show that 43.7% of all lengths below 50,000 have this issue.
for i in range(500):
a = set(range(i))
b = a.copy()
assert a == b
if a.__sizeof__() != b.__sizeof__():
print(f"{i}: True")
else:
print(f"{i}: False")My expectation is that the reported size would not change from copying a set.
Your environment
Tested on both Ubuntu and Debian with same results
- CPython versions tested on:
- 3.11.0
- 3.11.2
- Operating system and architecture:
- Ubuntu 22.04.2 LTS
- Debian GNU/Linux 12