Source code for crate_anon.common.memsize

"""
crate_anon/common/memsize.py

===============================================================================

    Copyright (C) 2015, University of Cambridge, Department of Psychiatry.
    Created by Rudolf Cardinal (rnc1001@cam.ac.uk).

    This file is part of CRATE.

    CRATE is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    CRATE is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with CRATE. If not, see <https://www.gnu.org/licenses/>.

===============================================================================

Calculate the size of objects in memory (fast).

From https://stackoverflow.com/questions/449560/how-do-i-determine-the-size-of-an-object-in-python

"""  # noqa

from gc import get_referents
from sys import getsizeof
from types import ModuleType, FunctionType
from typing import Any, List, Set

# Custom objects know their class.
# Function objects seem to know way too much, including modules.
# Exclude modules as well.
DENYLIST = type, ModuleType, FunctionType


[docs]def getsize(obj: Any, assume_none_denied: bool = False) -> int: """ Return the total size (in bytes) of the object and its members. From https://stackoverflow.com/questions/449560/how-do-i-determine-the-size-of-an-object-in-python Args: obj: Object to check. assume_none_denied: Skip checks for classes/modules/functions. Assume that all objects should be checked (typically, meaning that the caller guarantees not to pass stuff that doesn't need checking). """ # noqa if not assume_none_denied: if isinstance(obj, DENYLIST): raise TypeError( f"getsize() does not take argument of type: " f"{type(obj)}" ) seen_ids = set() # type: Set[int] size = 0 objects = [obj] # type: List[Any] while objects: need_referents = [] # type: List[Any] for obj in objects: if assume_none_denied or not isinstance(obj, DENYLIST): obj_id = id(obj) if obj_id not in seen_ids: seen_ids.add(obj_id) size += getsizeof(obj) need_referents.append(obj) objects = get_referents(*need_referents) return size