import time import argparse class TimerSubcategory: def __init__(self, timer, category): self.timer = timer self.category = category self.start = None self.original_base_category = timer.base_category def __enter__(self): self.start = time.time() self.timer.base_category = self.original_base_category + self.category + "/" self.timer.subcategory_level += 1 if self.timer.print_log: print(f"{' ' * self.timer.subcategory_level}{self.category}:") def __exit__(self, exc_type, exc_val, exc_tb): elapsed_for_subcategroy = time.time() - self.start self.timer.base_category = self.original_base_category self.timer.add_time_to_record(self.original_base_category + self.category, elapsed_for_subcategroy) self.timer.subcategory_level -= 1 self.timer.record(self.category, disable_log=True) class Timer: def __init__(self, print_log=False): self.start = time.time() self.records = {} self.total = 0 self.base_category = '' self.print_log = print_log self.subcategory_level = 0 def elapsed(self): end = time.time() res = end - self.start self.start = end return res def add_time_to_record(self, category, amount): if category not in self.records: self.records[category] = 0 self.records[category] += amount def record(self, category, extra_time=0, disable_log=False): e = self.elapsed() self.add_time_to_record(self.base_category + category, e + extra_time) self.total += e + extra_time if self.print_log and not disable_log: print(f"{' ' * self.subcategory_level}{category}: done in {e + extra_time:.3f}s") def subcategory(self, name): self.elapsed() subcat = TimerSubcategory(self, name) return subcat def summary(self): res = f"{self.total:.1f}s" additions = [(category, time_taken) for category, time_taken in self.records.items() if time_taken >= 0.1 and '/' not in category] if not additions: return res res += " (" res += ", ".join([f"{category}: {time_taken:.1f}s" for category, time_taken in additions]) res += ")" return res def dump(self): return {'total': self.total, 'records': self.records} def reset(self): self.__init__() parser = argparse.ArgumentParser(add_help=False) parser.add_argument("--log-startup", action='store_true', help="print a detailed log of what's happening at startup") args = parser.parse_known_args()[0] startup_timer = Timer(print_log=args.log_startup) startup_record = None