diff options
| author | bd <bdunahu@operationnull.com> | 2025-06-15 23:34:15 -0400 |
|---|---|---|
| committer | bd <bdunahu@operationnull.com> | 2025-06-15 23:34:15 -0400 |
| commit | 1a9808431219db676b4c7482992707584c3071e2 (patch) | |
| tree | aabeb6ff3d030c11c72188422d38ed1c1ac40e40 | |
| parent | 8844dceadcdeebf67d07656bf45d3ddada3e2b5b (diff) | |
Rename to Aergia
| -rw-r--r-- | aergia.py (renamed from mini_scalene.py) | 92 |
1 files changed, 33 insertions, 59 deletions
diff --git a/mini_scalene.py b/aergia.py index f7a8ca9..534880f 100644 --- a/mini_scalene.py +++ b/aergia.py @@ -1,18 +1,11 @@ -import selectors - import sys import argparse import threading import traceback -import atexit import signal import asyncio import time -from typing import ( - Any, - Callable, - cast, -) +from typing import cast from types import FrameType from collections import defaultdict import replacement_epoll_selector @@ -29,6 +22,7 @@ the_globals = { '__cached__': None, } + def parse_arguments(): '''Parse CLI args''' parser = argparse.ArgumentParser() @@ -45,12 +39,12 @@ def parse_arguments(): return parser.parse_args() -class MiniScalene(object): +class Aergia(object): '''A stripped-down version of SCALENE which tallies active lines during execution.''' # a key-value pair where keys represent frame metadata (see - # MiniScalene.frame_to_string) and values represent number of times + # Aergia.frame_to_string) and values represent number of times # sampled. cpu_samples = defaultdict(lambda: 0) cpu_samples_c = defaultdict(lambda: 0) @@ -72,7 +66,7 @@ class MiniScalene(object): signal.setitimer(signal.ITIMER_PROF, self.signal_interval, self.signal_interval) - MiniScalene.last_signal_time = MiniScalene.gettime() + Aergia.last_signal_time = Aergia.gettime() @staticmethod def gettime(): @@ -81,29 +75,29 @@ class MiniScalene(object): @staticmethod def start(profile_async): - MiniScalene.profile_async = profile_async + Aergia.profile_async = profile_async @staticmethod def stop(): '''Turn off profiling signals''' - MiniScalene.disable_signals() - MiniScalene.exit_handler() + Aergia.disable_signals() + Aergia.exit_handler() @staticmethod def exit_handler(): '''Pretty-print profiling information.''' # If we've collected any samples, dump them. print("CPU usage (Python):") - if MiniScalene.total_cpu_samples > 0: - for key in MiniScalene.sort_samples(MiniScalene.cpu_samples): + if Aergia.total_cpu_samples > 0: + for key in Aergia.sort_samples(Aergia.cpu_samples): print(f"{key} : " - f"{MiniScalene.cpu_samples[key] * 100 / MiniScalene.total_cpu_samples:.3f} % " - f"({MiniScalene.cpu_samples[key]:.1f} total samples)") + f"{Aergia.cpu_samples[key] * 100 / Aergia.total_cpu_samples:.3f} % " + f"({Aergia.cpu_samples[key]:.1f} total samples)") print("CPU usage (Native):") - for key in MiniScalene.sort_samples(MiniScalene.cpu_samples_c): + for key in Aergia.sort_samples(Aergia.cpu_samples_c): print(f"{key} : " - f"{MiniScalene.cpu_samples_c[key] * 100 / MiniScalene.total_cpu_samples:.3f} % " - f"({MiniScalene.cpu_samples_c[key]:.1f} total samples)") + f"{Aergia.cpu_samples_c[key] * 100 / Aergia.total_cpu_samples:.3f} % " + f"({Aergia.cpu_samples_c[key]:.1f} total samples)") else: print("(did not run long enough to profile)") @@ -115,30 +109,30 @@ class MiniScalene(object): @staticmethod def cpu_signal_handler(sig, frame): - elapsed_since_last_signal = MiniScalene.gettime() - \ - MiniScalene.last_signal_time + elapsed_since_last_signal = Aergia.gettime() - \ + Aergia.last_signal_time c_time_norm = (elapsed_since_last_signal - - MiniScalene.signal_interval) / \ - MiniScalene.signal_interval + Aergia.signal_interval) / \ + Aergia.signal_interval - keys = MiniScalene.compute_frames_to_record(frame) + keys = Aergia.compute_frames_to_record(frame) for key in keys: - MiniScalene.cpu_samples[MiniScalene.frame_to_string(key)] += 1 - MiniScalene.cpu_samples_c[MiniScalene.frame_to_string( + Aergia.cpu_samples[Aergia.frame_to_string(key)] += 1 + Aergia.cpu_samples_c[Aergia.frame_to_string( key)] += c_time_norm - MiniScalene.total_cpu_samples += elapsed_since_last_signal / \ - MiniScalene.signal_interval - MiniScalene.last_signal_time = MiniScalene.gettime() + Aergia.total_cpu_samples += elapsed_since_last_signal / \ + Aergia.signal_interval + Aergia.last_signal_time = Aergia.gettime() @staticmethod def compute_frames_to_record(this_frame): - '''Collects all stack frames that Scalene actually processes.''' + '''Collects all stack frames that Aergia actually processes.''' frames = [this_frame] frames += [sys._current_frames().get(t.ident, None) for t in threading.enumerate()] - frames += MiniScalene.get_async_frames() + frames += Aergia.get_async_frames() - frames = MiniScalene.filter_duplicated_frames(frames) + frames = Aergia.filter_duplicated_frames(frames) # Process all the frames to remove ones we aren't going to track. new_frames = [] for frame in frames: @@ -151,7 +145,7 @@ class MiniScalene(object): # to look back into the outer frame in order to check # the co_filename. fname = frame.f_back.f_code.co_filename - while not MiniScalene.should_trace(fname): + while not Aergia.should_trace(fname): # Walk the stack backwards until we hit a frame that # IS one we should trace (if there is one). i.e., if # it's in the code being profiled, and it is just @@ -179,7 +173,7 @@ class MiniScalene(object): @staticmethod def get_async_frames(): '''Obtains the stack frames of all currently executing tasks.''' - if MiniScalene.is_event_loop_running() and MiniScalene.profile_async: + if Aergia.is_event_loop_running() and Aergia.profile_async: return [task.get_coro().cr_frame for task in asyncio.all_tasks()] return [] @@ -191,7 +185,7 @@ class MiniScalene(object): return False if filename[0] == '<': return False - if 'mini_scalene.py' in filename: + if 'aergia.py' in filename: return False return True @@ -209,26 +203,6 @@ class MiniScalene(object): reverse=True)} @staticmethod - def shim(func: Callable[[Any], Any]) -> Any: - """Provide a decorator that calls the wrapped function with the - Scalene variant. - - Wrapped function must be of type (s: Scalene) -> Any. - - This decorator allows for marking a function in a separate - file as a drop-in replacement for an existing library - function. The intention is for these functions to replace a - function that indefinitely blocks (which interferes with - Scalene) with a function that awakens periodically to allow - for signals to be delivered. - - """ - func(MiniScalene) - # Returns the function itself to the calling file for the sake - # of not displaying unusual errors if someone attempts to call - # it - - @staticmethod def filter_duplicated_frames(frames) -> bool: s = set() dup = [] @@ -254,9 +228,9 @@ def main(): try: with open(args.script, 'rb') as fp: code = compile(fp.read(), args.script, "exec") - MiniScalene().start(args.async_off) + Aergia().start(args.async_off) exec(code, the_globals) - MiniScalene().stop() + Aergia().stop() except Exception: traceback.print_exc() |
