processing profiler

This commit is contained in:
2022-02-22 19:59:38 +01:00
parent 361ad22ee6
commit f140256e37
3 changed files with 216 additions and 0 deletions

152
procprof/procprof.py Executable file
View File

@ -0,0 +1,152 @@
#!/usr/bin/env python3
#fn_proc = "spectrometer.py"
#fn_proc = "do_nothing.py"
#fn_imgs = "example_images.npy"
import argparse
parser = argparse.ArgumentParser(description="Profile a Processing Script")
parser.add_argument("proc", help="processing script")
parser.add_argument("imgs", help="example images as numpy dump")
clargs = parser.parse_args()
from datetime import datetime
import cProfile as profile
import importlib
import numpy as np
import os
import pstats
import timeit
PROC_FUNC_NAME = "process_image"
def main(fn_proc, fn_imgs):
proc = proc_import(fn_proc)
imgs = np.load(fn_imgs)
pulse_id = timestamp = x_axis = y_axis = None
parameters = {
"camera_name": "test"
}
def test():
for i, img in enumerate(imgs):
# print(i)
res = proc(
img,
pulse_id, timestamp, x_axis, y_axis, parameters
)
timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
os.makedirs("prof", exist_ok=True)
fn_base_res = f"prof/{fn_proc}-{timestamp}"
func_profile(test, fn_base_res)
func_timeit(test, fn_base_res)
# profiling
def func_profile(func, fn):
p = profile.Profile()
p.runcall(func)
p.print_stats()
fn_prof = fn + ".prof"
p.dump_stats(fn_prof)
fn_res = fn + ".result"
write_stats(p, fn_res)
def write_stats(p, fn):
with open(fn, "x") as f:
s = pstats.Stats(p, stream=f)
s.print_stats()
# timing
def func_timeit(func, fn, repeat=3, number=1):
t = timeit.Timer(func)
res = t.repeat(repeat=repeat, number=number)
res = np.array(res)
res /= number
desc = np_describe(res)
desc = printable_dict(desc)
print(desc)
fn_res = fn + ".timing"
with open(fn_res, "x") as f:
f.write(str(res.tolist()))
f.write("\n\n")
f.write(desc)
def np_describe(a):
a = np.asarray(a)
aggrs = (
min, max,
np.median, np.mean,
np.var, np.std
)
return {f.__name__: f(a) for f in aggrs}
def printable_dict(d, header=None):
length = maxstrlen(d) + 1
lines = ("{}:{}{}".format(k, " "*(length-strlen(k)), v) for k, v in d.items())
if header:
header = format_header(header)
lines = [header] + lines
return "\n".join(lines) + "\n"
def maxstrlen(seq):
seq = [str(i) for i in seq]
return maxlen(seq)
def maxlen(seq):
if not seq: # max of empty sequence is a ValueError
return 0
return max(len(i) for i in seq)
def strlen(x):
return len(str(x))
# importing
def proc_import(fn):
proc = fn_import(fn)
if not hasattr(proc, PROC_FUNC_NAME):
msg = f"file \"{fn}\" does not contain processing function: {PROC_FUNC_NAME}"
raise ValueError(msg)
return proc.process_image
def fn_import(fn):
mod = remove_suffix(fn, ".py")
return importlib.import_module(mod)
def remove_suffix(string, suffix):
if string.endswith(suffix):
string = string[:-len(suffix)]
return string
if __name__ == "__main__":
main(clargs.proc, clargs.imgs)