object size measurement function, related to #7
This commit is contained in:
38
src/dopt_basics/system.py
Normal file
38
src/dopt_basics/system.py
Normal file
@@ -0,0 +1,38 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from dataclasses import fields, is_dataclass
|
||||
from typing import Any, Literal
|
||||
|
||||
|
||||
def obj_size(
|
||||
obj: Any,
|
||||
seen: set[int] | None = None,
|
||||
unit: Literal["b", "kb", "mb", "gb"] = "b",
|
||||
) -> float:
|
||||
size = sys.getsizeof(obj)
|
||||
if seen is None:
|
||||
seen = set()
|
||||
|
||||
obj_id = id(obj)
|
||||
if obj_id in seen:
|
||||
return 0
|
||||
seen.add(obj_id)
|
||||
|
||||
if is_dataclass(obj):
|
||||
for f in fields(obj):
|
||||
size += obj_size(getattr(obj, f.name), seen)
|
||||
elif isinstance(obj, dict):
|
||||
size += sum(obj_size(v, seen) + obj_size(k, seen) for k, v in obj.items())
|
||||
elif isinstance(obj, (list, tuple, set)):
|
||||
size += sum(obj_size(i, seen) for i in obj)
|
||||
|
||||
match unit:
|
||||
case "kb":
|
||||
size /= 1024
|
||||
case "mb":
|
||||
size /= 1024 * 1024
|
||||
case "gb":
|
||||
size /= 1024 * 1024 * 1024
|
||||
|
||||
return size
|
||||
Reference in New Issue
Block a user