Skip to content

Instantly share code, notes, and snippets.

@Girgitt
Last active February 28, 2024 09:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Girgitt/a00961fc54f42163a24dcfc335865ed4 to your computer and use it in GitHub Desktop.
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.
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)
@Girgitt
Copy link
Author

Girgitt commented Jun 15, 2023

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment