Skip to content

Instantly share code, notes, and snippets.

@ephes
Created February 21, 2024 23:20
Show Gist options
  • Save ephes/db0c6570d8c91bf524f98057273d4c4d to your computer and use it in GitHub Desktop.
Save ephes/db0c6570d8c91bf524f98057273d4c4d to your computer and use it in GitHub Desktop.
Memory usage __dict__ vs __slots__
import string
import random
long_key = "a_key_with_a_very_long_name_"
class Test:
def __init__(self):
for i in range(20):
v = "".join(random.choices(string.ascii_lowercase, k=20))
setattr(self, f"{long_key}{i:02}", v)
import sys
import resource
import importlib
module = None
if len(sys.argv) == 2:
module_name = sys.argv[1].replace(".py", "")
module = importlib.import_module(module_name)
else:
print(f"Usage: {sys.argv[0]} <class-module-to-test>")
fmt = "Selected Test type: {.__name__}.{.__name__}"
print(fmt.format(module, module.Test))
cls = module.Test
NUM_CLASSES = 10**6
mem_init = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
print(f"Creating {NUM_CLASSES:,} {cls.__qualname__!r} instances")
instances = [cls() for _ in range(NUM_CLASSES)]
mem_final = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
print(f"Initial RAM usage: {mem_init:14,}")
print(f" Final RAM usage: {mem_final:14,}")
$ time python mem_test.py dict
Selected Test type: dict.Test
Creating 1,000,000 'Test' instances
Initial RAM usage: 12,058,624
Final RAM usage: 1,546,305,536
________________________________________________________
Executed in 35.14 secs fish external
usr time 34.74 secs 0.07 millis 34.74 secs
sys time 0.27 secs 1.13 millis 0.26 secs
$ time python mem_test.py slots
Selected Test type: slots.Test
Creating 1,000,000 'Test' instances
Initial RAM usage: 12,288,000
Final RAM usage: 1,498,284,032
________________________________________________________
Executed in 35.12 secs fish external
usr time 34.64 secs 0.07 millis 34.64 secs
sys time 0.25 secs 1.15 millis 0.25 secs
time python vector_test.py vector
Selected Test type: vector.Vector2d
Creating 10,000,000 'Vector2d' instances
Initial RAM usage: 10,960,896
Final RAM usage: 901,316,608
________________________________________________________
Executed in 4.77 secs fish external
usr time 4.61 secs 0.09 millis 4.61 secs
sys time 0.13 secs 1.47 millis 0.13 secs
$ time python vector_test.py vector_slots
Selected Test type: vector_slots.Vector2d
Creating 10,000,000 'Vector2d' instances
Initial RAM usage: 10,993,664
Final RAM usage: 583,335,936
________________________________________________________
Executed in 3.93 secs fish external
usr time 3.81 secs 0.09 millis 3.81 secs
sys time 0.10 secs 1.73 millis 0.10 secs
import string
import random
long_key = "a_key_with_a_very_long_name_"
class Test:
__slots__ = tuple([f"{long_key}{i:02}" for i in range(20)])
def __init__(self):
for i in range(20):
v = "".join(random.choices(string.ascii_lowercase, k=20))
setattr(self, f"{long_key}{i:02}", v)
class Vector2d:
def __init__(self, x, y):
self.x = float(x)
self.y = float(y)
class Vector2d:
__slots__ = ("x", "y")
def __init__(self, x, y):
self.x = float(x)
self.y = float(y)
import sys
import resource
import importlib
module = None
if len(sys.argv) == 2:
module_name = sys.argv[1].replace(".py", "")
module = importlib.import_module(module_name)
else:
print(f"Usage: {sys.argv[0]} <class-module-to-test>")
fmt = "Selected Test type: {.__name__}.{.__name__}"
print(fmt.format(module, module.Vector2d))
cls = module.Vector2d
NUM_VECTORS = 10**7
mem_init = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
print(f"Creating {NUM_VECTORS:,} {cls.__qualname__!r} instances")
vectors = [cls(3.0, 4.0) for i in range(NUM_VECTORS)]
mem_final = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
print(f"Initial RAM usage: {mem_init:14,}")
print(f" Final RAM usage: {mem_final:14,}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment