diff options
| -rwxr-xr-x[-rw-r--r--] | aergia (renamed from aergia.py) | 41 |
1 files changed, 13 insertions, 28 deletions
@@ -1,3 +1,4 @@ +#!/usr/bin/env python3 ''' _/_/ _/ _/ _/ _/_/ _/ _/_/ _/_/_/ _/_/_/ @@ -27,14 +28,14 @@ Copyright: Commentary: Aergia is a sampling based profiler based off of SCALENE - (https://github.com/plasma-umass/scalene). + by Emery Berger (https://github.com/plasma-umass/scalene). It is not particularly informative, but unlike SCALENE or other sampling-based profilers I could find, reports the wall-time each asyncio await call spends idling. - The goal behind Aergia is to eventually have these - features, or similar, merged into SCALENE. + The goal behind Aergia is to eventually have these features, + or similar, merged into SCALENE. Code: @@ -94,9 +95,6 @@ class Aergia(object): # the timestamp recorded last signal last_signal_time = 0.0 - # if we should try to profile asynchronous code. Used to observe - # effectiveness of the implementation. - profile_async = True def __init__(self): signal.signal(signal.SIGPROF, @@ -104,16 +102,15 @@ class Aergia(object): signal.setitimer(signal.ITIMER_PROF, self.signal_interval, self.signal_interval) - Aergia.last_signal_time = Aergia.gettime() @staticmethod def gettime(): '''get the wallclock time''' - return time.perf_counter() + return time.time() @staticmethod def start(profile_async): - Aergia.profile_async = profile_async + Aergia.last_signal_time = Aergia.gettime() @staticmethod def stop(): @@ -137,7 +134,7 @@ class Aergia(object): 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)") + print("(Bug) The program did not run long enough to profile, or a one-time error occured.") @staticmethod def disable_signals(): @@ -153,7 +150,7 @@ class Aergia(object): Aergia.signal_interval) / \ Aergia.signal_interval - keys = Aergia.compute_frames_to_record(frame) + keys = Aergia.compute_frames_to_record() for key in keys: Aergia.cpu_samples[Aergia.frame_to_string(key)] += 1 Aergia.cpu_samples_c[Aergia.frame_to_string( @@ -163,14 +160,11 @@ class Aergia(object): Aergia.last_signal_time = Aergia.gettime() @staticmethod - def compute_frames_to_record(this_frame): + def compute_frames_to_record(): '''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 += Aergia.get_async_frames() + if Aergia.is_event_loop_running(): + frames = [task.get_coro().cr_frame for task in asyncio.all_tasks()] - 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: @@ -209,21 +203,14 @@ class Aergia(object): return filename + '\t' + func_name + '\t' + str(line_no) @staticmethod - def get_async_frames(): - '''Obtains the stack frames of all currently executing tasks.''' - if Aergia.is_event_loop_running() and Aergia.profile_async: - return [task.get_coro().cr_frame for task in asyncio.all_tasks()] - return [] - - @staticmethod def should_trace(filename): '''Returns FALSE if filename is uninteresting to the user.''' # FIXME Assume GuixSD. Makes filtering easy - if '/gnu/store' in filename: + if 'site-packages' in filename: return False if filename[0] == '<': return False - if 'aergia.py' in filename: + if 'aergia' in filename: return False return True @@ -311,5 +298,3 @@ def main(): if __name__ == "__main__": main() - -# aergia.py ends here |
