4 changed files with 308 additions and 0 deletions
@ -0,0 +1,234 @@ |
|||
#!/usr/bin/python |
|||
|
|||
from sys import getsizeof |
|||
|
|||
from gc import is_tracked,get_referents |
|||
|
|||
def quick_reachable_words(v): |
|||
seen = set() |
|||
|
|||
def aux(v): |
|||
v_id = id(v) |
|||
if v_id in seen: |
|||
return 0 |
|||
seen.add(v_id) |
|||
return getsizeof(v) + sum(map(quick_reachable_words, get_referents(v))) |
|||
|
|||
return aux(v) |
|||
|
|||
|
|||
print(quick_reachable_words(None)) |
|||
print(quick_reachable_words([1, 2, 3])) |
|||
|
|||
# from https://code.activestate.com/recipes/577504/ |
|||
# and https://github.com/progval/Supybot-plugins/blob/master/MemoryProfiler/plugin.py#L74-L124 |
|||
# see also https://github.com/pympler/pympler/blob/master/pympler/asizeof.py |
|||
def reachable_words(v): |
|||
seen = set() |
|||
|
|||
def aux(v): |
|||
v_id = id(v) |
|||
if v_id in seen: |
|||
return 0 |
|||
seen.add(v_id) |
|||
size = getsizeof(v) |
|||
|
|||
# TODO: https://docs.python.org/3/library/stdtypes.html#iterator-types |
|||
# TODO: deque ? |
|||
# TODO: https://docs.python.org/3/library/stdtypes.html#context-manager-types |
|||
# TODO: https://docs.python.org/3/library/stdtypes.html#type-annotation-types-generic-alias-union |
|||
|
|||
match v: |
|||
case bool(): |
|||
print("bool") |
|||
# this is 24 for False and 28 for True |
|||
# it's because False is represented as 0 and True as 1 (see below) |
|||
return size |
|||
case int(): |
|||
print("int") |
|||
# 0 -> 24 |
|||
# 1 .. 2^30 - 1 -> 28 |
|||
# 2^30 .. 2^60 - 1 -> 32 |
|||
# 2^(30n) .. 2^(30(n + 1)) - 1 -> 28 + 4n |
|||
# it's a list of 30bits blocks, see https://github.com/python/cpython/blob/main/Include/cpython/longintrepr.h |
|||
# it can be configured to be 15 instead of 30 |
|||
return size |
|||
case float(): |
|||
print("float") |
|||
case complex(): |
|||
print("complex") |
|||
case list(): |
|||
print("list") |
|||
case tuple(): |
|||
print("tuple") |
|||
case range(): |
|||
print("range") |
|||
case str(): |
|||
print("string") |
|||
case bytes(): |
|||
print("bytes") |
|||
case bytearray(): |
|||
print("bytearray") |
|||
case memoryview(): |
|||
print("memoryview") |
|||
case set(): |
|||
print("set") |
|||
case frozenset(): |
|||
print("frozenset") |
|||
case dict(): |
|||
print("dict") |
|||
#case view(): |
|||
# print("view") |
|||
case object(): |
|||
print("object") |
|||
case None: |
|||
print("None") |
|||
case v_type: |
|||
print("unhandled type:", v_type) |
|||
exit(1) |
|||
|
|||
return size |
|||
|
|||
return aux(v) |
|||
|
|||
''' |
|||
dict_handler = lambda d: chain.from_iterable(list(d.items())) |
|||
all_handlers = {tuple: iter, |
|||
list: iter, |
|||
deque: iter, |
|||
dict: dict_handler, |
|||
set: iter, |
|||
frozenset: iter, |
|||
str: None, |
|||
} |
|||
all_handlers.update(handlers) # user handlers take precedence |
|||
seen = set() # track which object id's have already been seen |
|||
default_size = getsizeof(0) # estimate sizeof object without __sizeof__ |
|||
|
|||
def sizeof(o): |
|||
if id(o) in seen: # do not double count the same object |
|||
return 0 |
|||
seen.add(id(o)) |
|||
s = getsizeof(o, default_size) |
|||
|
|||
if verbose: |
|||
print(s, type(o), repr(o), file=stderr) |
|||
|
|||
for typ, handler in all_handlers.items(): |
|||
if isinstance(o, typ): |
|||
if handler: |
|||
try: |
|||
s += sum(map(sizeof, handler(o))) |
|||
except RuntimeError: |
|||
pass |
|||
break |
|||
else: |
|||
if not object_filter or object_filter(o): |
|||
try: |
|||
s += sum(map(sizeof, list_attrs(o))) |
|||
except RuntimeError: |
|||
pass |
|||
return s |
|||
|
|||
return sum(map(sizeof, objects)) |
|||
''' |
|||
|
|||
# https://stackoverflow.com/questions/449560/how-do-i-determine-the-size-of-an-object-in-python |
|||
''' |
|||
import sys |
|||
from types import ModuleType, FunctionType |
|||
from gc import get_referents |
|||
|
|||
# Custom objects know their class. |
|||
# Function objects seem to know way too much, including modules. |
|||
# Exclude modules as well. |
|||
BLACKLIST = type, ModuleType, FunctionType |
|||
|
|||
|
|||
def getsize(obj): |
|||
"""sum size of object & members.""" |
|||
if isinstance(obj, BLACKLIST): |
|||
raise TypeError('getsize() does not take argument of type: '+ str(type(obj))) |
|||
seen_ids = set() |
|||
size = 0 |
|||
objects = [obj] |
|||
while objects: |
|||
need_referents = [] |
|||
for obj in objects: |
|||
if not isinstance(obj, BLACKLIST) and id(obj) not in seen_ids: |
|||
seen_ids.add(id(obj)) |
|||
size += sys.getsizeof(obj) |
|||
need_referents.append(obj) |
|||
objects = get_referents(*need_referents) |
|||
return size |
|||
''' |
|||
|
|||
def print_info(v): |
|||
print("it has repr :", repr(v)) |
|||
print("it has type :", type(v)) |
|||
print("it has id :", hex(id(v))) |
|||
print("it has dir :", dir(v)) |
|||
if hasattr(v, "__dict__"): |
|||
if callable(v.__dict__): |
|||
print("it has __dict__() :", v.__dict__) |
|||
else: |
|||
print("it has __dict__ :", v.__dict__) |
|||
else: |
|||
print("it has no __dict__ attribute !") |
|||
print("it has size :", getsizeof(v)) |
|||
print("it has deep size :", reachable_words(v)) |
|||
print("") |
|||
|
|||
|
|||
def f(x, y): |
|||
s = "hello" |
|||
return x + y + s |
|||
|
|||
''' |
|||
def main(): |
|||
print_info(1) |
|||
print_info(256) |
|||
print_info(102030) |
|||
print_info(None) |
|||
print_info(object()) |
|||
print_info("hello") |
|||
print_info({}) |
|||
print_info(dir(None)) |
|||
print_info(f) |
|||
print_info([1, 2, 3]) |
|||
print_info([{}]) |
|||
print_info([{}, {}, {}, {}]) |
|||
print_info([{"aaaaaaaaa", "bbbbbbbbbbb"}, {"aaaaaaaaa", "bbbbbbbbbbb"}, {"ccccc", 32}, {"djdjlk", 49}]) |
|||
''' |
|||
|
|||
def main(): |
|||
print(reachable_words(None)) |
|||
print(reachable_words(True)) |
|||
print(reachable_words(0)) |
|||
print(reachable_words(0.5)) |
|||
print(reachable_words(complex(42,24))) |
|||
print(reachable_words([])) |
|||
print(reachable_words([1, 2, 3])) |
|||
print(reachable_words([{}, {}, {}])) |
|||
print(reachable_words([{1, 2, 3, 4}, {1, "hjehje", 3.5, "jkdjlesjflk"}, {43, 'jkllkj', "jkljkj", "jjjjjjjj"}])) |
|||
print(reachable_words((None, None))) |
|||
print(reachable_words((None, None, None))) |
|||
print(reachable_words((1, 2, 3))) |
|||
print(reachable_words(range(6))) |
|||
|
|||
main() |
|||
|
|||
# locals |
|||
# globals |
|||
# vars |
|||
# delattr |
|||
# dir |
|||
# getattr |
|||
# hasattr |
|||
# isinstance |
|||
# memoryview |
|||
# object |
|||
# property |
|||
# repr |
|||
# setattr |
|||
# type |
@ -0,0 +1,19 @@ |
|||
#/usr/bin/python3 |
|||
|
|||
class C: |
|||
__match_args__ = ("y", "x") |
|||
def __init__(self, x, y): |
|||
self.x = x |
|||
self.y = y |
|||
|
|||
c = C(C(1, 2), C(3, 4)) |
|||
|
|||
match c: |
|||
case C(y=C(4, 3)): |
|||
print(3, 4) |
|||
case C(C(1, 2), _): |
|||
print(1, 2) |
|||
case C(C(4, 3), C(2, 1)): |
|||
print(4, 3) |
|||
case _: |
|||
print("default") |
@ -0,0 +1,20 @@ |
|||
type t = .. |
|||
|
|||
type t += Coucou |
|||
|
|||
let f (x : string) : (string, t) Result.t = |
|||
Ok x |
|||
|
|||
let () = |
|||
match f "coucou" with |
|||
| Ok x -> print_endline x |
|||
| _ -> assert false |
|||
|
|||
let v = Coucou |
|||
|
|||
let f = function |
|||
| Coucou -> print_endline "aaaa" |
|||
|
|||
type t += Bite |
|||
|
|||
let () = () |
Loading…
Reference in new issue