Last active
February 28, 2024 09:06
-
-
Save Girgitt/a00961fc54f42163a24dcfc335865ed4 to your computer and use it in GitHub Desktop.
small class to quickly profile execution in python without decomposing your code into functions to use "timeit" decorators etc.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ProfilerLog(object): | |
def __init__(self, profiler_name="", start_ts=None): | |
self._profiler_name = profiler_name | |
self._start_ts = start_ts if start_ts else time.time() | |
self._steps_data = OrderedDict() | |
self._aux_data = {} | |
def step(self, step_name, begin_ts=None, end_ts=None): | |
if step_name not in self._steps_data: | |
begin_ts = begin_ts if begin_ts else time.time() | |
self._steps_data[step_name] = {'begin_ts': begin_ts, 'end_ts': end_ts} | |
else: | |
end_ts = end_ts if end_ts else time.time() | |
self._steps_data[step_name]['end_ts'] = end_ts | |
def get_formatted_step_log(self, step_name): | |
if step_name in self._steps_data: | |
step_data = self._steps_data.get(step_name) | |
if step_data.get('begin_ts'): | |
if step_data.get('end_ts'): | |
step_took_sec = step_data.get('end_ts') - step_data.get('begin_ts') | |
since_start_took_sec = step_data.get('end_ts') - self._start_ts | |
step_duration_str = "%.3f" % step_took_sec | |
since_start_duration_str = "%.3f" % since_start_took_sec | |
return f"profiling {self._profiler_name} step: {step_name}: {step_duration_str} s (total: {since_start_duration_str}s)" | |
else: | |
return f"profiling {self._profiler_name} step: {step_name} ERROR: missing end ts" | |
else: | |
return f"profiling {self._profiler_name} step: {step_name} ERROR: missing begin ts" | |
def get_formatted_step_aux_log(self, step_name, msg): | |
if step_name == 'no_stop_prefix': | |
return f"profiling {self._profiler_name} {msg}" | |
elif step_name != 'default': | |
return f"profiling {self._profiler_name} |_ {msg}" | |
# return f"profiling {self._profiler_name} step: {step_name} |_detail: {msg}" | |
return f"profiling {self._profiler_name} |_ {msg}" | |
def log_step(self, step_name=None, include_aux=True): | |
for stored_step_name in self._steps_data: | |
if step_name: | |
if stored_step_name == step_name: | |
step_profile_str = self.get_formatted_step_log(stored_step_name) | |
log.info(step_profile_str) | |
break | |
else: | |
step_profile_str = self.get_formatted_step_log(stored_step_name) | |
log.info(step_profile_str) | |
if include_aux: | |
for msg in self._aux_data.get(stored_step_name, []): | |
log.info(self.get_formatted_step_aux_log(stored_step_name, msg)) | |
if include_aux: | |
if self._aux_data.get('default', []): | |
log.info(self.get_formatted_step_aux_log('no_stop_prefix', "[default details]")) | |
for msg in self._aux_data.get('default', []): | |
log.info(self.get_formatted_step_aux_log('default', msg)) | |
def log_detail(self, msg, step_name='default'): | |
try: | |
self._aux_data[step_name].append(msg) | |
except KeyError: | |
self._aux_data[step_name] = [] | |
self._aux_data[step_name].append(msg) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Use by invoking "step" method twice around code to profile:
step_prof = ProfilerLog(profiler_name="0000001.csv", start_ts=time.time())
step_prof.step('csv_load')
data = get_current_data_part_csv_as_dataframe("0000001.csv", skiprows=lines_to_skip)
step_prof.step('csv_load')
at the end call "log_step" with optional step name. With no step name passed all registered steps are logged:
step_prof.log_step()
which will produce output similar to this:
2023-06-15 15:33:30,311 [INFO ]: profiling 0000001.csv step: getting_lines_to_skip: 2.210 s (total: 2.210s)
2023-06-15 15:33:30,312 [INFO ]: profiling 0000001.csv step: csv_load: 1.077 s (total: 3.288s)
2023-06-15 15:33:30,312 [INFO ]: profiling 0000001.csv step: next_part_csv_load: 0.041 s (total: 3.329s)
2023-06-15 15:33:30,312 [INFO ]: profiling 0000001.csv step: 1s_downsampling: 18.821 s (total: 22.358s)
2023-06-15 15:33:30,312 [INFO ]: profiling 0000001.csv step: 1s_downsampling - analog re-write, parsing datetime: 16.542 s (total: 20.079s)
2023-06-15 15:33:30,312 [INFO ]: profiling 0000001.csv step: 1s_downsampling - analog re-write, filtering from: 0.053 s (total: 20.132s)
2023-06-15 15:33:30,312 [INFO ]: profiling 0000001.csv step: 1s_downsampling - analog re-write, converting epoch: 2.226 s (total: 22.358s)
2023-06-15 15:33:30,312 [INFO ]: profiling 0000001.csv step: head_tail_trimming: 0.009 s (total: 22.368s)
2023-06-15 15:33:30,312 [INFO ]: profiling 0000001.csv step: interpolation: 11.747 s (total: 34.115s)