diff --git a/RNS/Reticulum.py b/RNS/Reticulum.py index df7851db..839befad 100755 --- a/RNS/Reticulum.py +++ b/RNS/Reticulum.py @@ -162,8 +162,8 @@ def exit_handler(): RNS.Transport.exit_handler() RNS.Identity.exit_handler() - if RNS.profiler_ran: - RNS.profiler_results() + if RNS.Profiler.ran(): + RNS.Profiler.results() @staticmethod def sigint_handler(signal, frame): diff --git a/RNS/__init__.py b/RNS/__init__.py index 177d39b7..2466ab4e 100755 --- a/RNS/__init__.py +++ b/RNS/__init__.py @@ -348,93 +348,101 @@ def exit(): print("") sys.exit(0) +class Profiler: + ran = False + tags = {} -profiler_ran = False -profiler_tags = {} -def profiler(tag=None, capture=False, super_tag=None): - global profiler_ran, profiler_tags - try: - thread_ident = threading.get_ident() - - if capture: - end = time.perf_counter() - if tag in profiler_tags and thread_ident in profiler_tags[tag]["threads"]: - if profiler_tags[tag]["threads"][thread_ident]["current_start"] != None: - begin = profiler_tags[tag]["threads"][thread_ident]["current_start"] - profiler_tags[tag]["threads"][thread_ident]["current_start"] = None - profiler_tags[tag]["threads"][thread_ident]["captures"].append(end-begin) - if not profiler_ran: - profiler_ran = True + def __init__(self, tag=None, super_tag=None): + self.tag = tag + self.super_tag = super_tag - else: - if not tag in profiler_tags: - profiler_tags[tag] = {"threads": {}, "super": super_tag} - if not thread_ident in profiler_tags[tag]["threads"]: - profiler_tags[tag]["threads"][thread_ident] = {"current_start": None, "captures": []} - - profiler_tags[tag]["threads"][thread_ident]["current_start"] = time.perf_counter() + def __enter__(self): + tag = self.tag + super_tag = self.super_tag + thread_ident = threading.get_ident() + if not tag in Profiler.tags: + Profiler.tags[tag] = {"threads": {}, "super": super_tag} + if not thread_ident in Profiler.tags[tag]["threads"]: + Profiler.tags[tag]["threads"][thread_ident] = {"current_start": None, "captures": []} - except Exception as e: - trace_exception(e) + Profiler.tags[tag]["threads"][thread_ident]["current_start"] = time.perf_counter() -def profiler_results(): - from statistics import mean, median, stdev - results = {} - - for tag in profiler_tags: - tag_captures = [] - tag_entry = profiler_tags[tag] + def __exit__(self, exc_type, exc_value, traceback): + tag = self.tag + super_tag = self.super_tag + end = time.perf_counter() + thread_ident = threading.get_ident() + if tag in Profiler.tags and thread_ident in Profiler.tags[tag]["threads"]: + if Profiler.tags[tag]["threads"][thread_ident]["current_start"] != None: + begin = Profiler.tags[tag]["threads"][thread_ident]["current_start"] + Profiler.tags[tag]["threads"][thread_ident]["current_start"] = None + Profiler.tags[tag]["threads"][thread_ident]["captures"].append(end-begin) + if not Profiler.ran: + Profiler.ran = True + + @staticmethod + def ran(): + return Profiler.ran + + @staticmethod + def results(): + from statistics import mean, median, stdev + results = {} - for thread_ident in tag_entry["threads"]: - thread_entry = tag_entry["threads"][thread_ident] - thread_captures = thread_entry["captures"] - sample_count = len(thread_captures) + for tag in Profiler.tags: + tag_captures = [] + tag_entry = Profiler.tags[tag] + for thread_ident in tag_entry["threads"]: + thread_entry = tag_entry["threads"][thread_ident] + thread_captures = thread_entry["captures"] + sample_count = len(thread_captures) + + if sample_count > 2: + thread_results = { + "count": sample_count, + "mean": mean(thread_captures), + "median": median(thread_captures), + "stdev": stdev(thread_captures) + } + + tag_captures.extend(thread_captures) + + sample_count = len(tag_captures) if sample_count > 2: - thread_results = { - "count": sample_count, - "mean": mean(thread_captures), - "median": median(thread_captures), - "stdev": stdev(thread_captures) + tag_results = { + "name": tag, + "super": tag_entry["super"], + "count": len(tag_captures), + "mean": mean(tag_captures), + "median": median(tag_captures), + "stdev": stdev(tag_captures) } - tag_captures.extend(thread_captures) + results[tag] = tag_results + + def print_results_recursive(tag, results, level=0): + print_tag_results(tag, level+1) - sample_count = len(tag_captures) - if sample_count > 2: - tag_results = { - "name": tag, - "super": tag_entry["super"], - "count": len(tag_captures), - "mean": mean(tag_captures), - "median": median(tag_captures), - "stdev": stdev(tag_captures) - } + for tag_name in results: + sub_tag = results[tag_name] + if sub_tag["super"] == tag["name"]: + print_results_recursive(sub_tag, results, level=level+1) - results[tag] = tag_results - def print_results_recursive(tag, results, level=0): - print_tag_results(tag, level+1) + def print_tag_results(tag, level): + ind = " "*level + name = tag["name"]; count = tag["count"] + mean = tag["mean"]; median = tag["median"]; stdev = tag["stdev"] + print(f"{ind}{name}") + print(f"{ind} Samples : {count}") + print(f"{ind} Mean : {prettyshorttime(mean)}") + print(f"{ind} Median : {prettyshorttime(median)}") + print(f"{ind} St.dev. : {prettyshorttime(stdev)}") + print("") + print("\nProfiler results:\n") for tag_name in results: - sub_tag = results[tag_name] - if sub_tag["super"] == tag["name"]: - print_results_recursive(sub_tag, results, level=level+1) - - - def print_tag_results(tag, level): - ind = " "*level - name = tag["name"]; count = tag["count"] - mean = tag["mean"]; tag["median"]; stdev = tag["stdev"] - print(f"{ind}{name}") - print(f"{ind} Samples : {count}") - print(f"{ind} Mean : {prettyshorttime(mean)}") - print(f"{ind} Median : {prettyshorttime(median)}") - print(f"{ind} St.dev. : {prettyshorttime(stdev)}") - print("") - - print("\nProfiler results:\n") - for tag_name in results: - tag = results[tag_name] - if tag["super"] == None: - print_results_recursive(tag, results) + tag = results[tag_name] + if tag["super"] == None: + print_results_recursive(tag, results)