diff --git a/aoclib/performance.py b/aoclib/performance.py index 48428d3..d289069 100644 --- a/aoclib/performance.py +++ b/aoclib/performance.py @@ -1,13 +1,11 @@ import time -def print_execution_time(func): - def wrapper(*args, **kwargs): - time_start = time.time() - return_value = func(*args, **kwargs) - time_stop = time.time() - print('{:s} function took {:.3f}ms'.format(func.__name__, (time_stop - time_start) * 1000.0)) +def print_execution_time(day, part, avg_time): + units = ['s', 'ms', 'μs', 'ns'] + unit = 0 + while avg_time < 1: + avg_time *= 1000 + unit += 1 - return return_value - - return wrapper + print("Average execution time for day %s part %s: %1.2f%s" % (day, part, avg_time, units[unit])) diff --git a/day01.py b/day01.py index bcf23a2..5f72a32 100755 --- a/day01.py +++ b/day01.py @@ -18,13 +18,11 @@ def getProductOf2020Sum(input_lines, combinations): return return_value -@aoclib.print_execution_time def part1(test_mode=False): my_input = aoclib.getInputAsArray(day=DAY, return_type=int, test=test_mode) return getProductOf2020Sum(my_input, 2) -@aoclib.print_execution_time def part2(test_mode=False): my_input = aoclib.getInputAsArray(day=DAY, return_type=int, test=test_mode) return getProductOf2020Sum(my_input, 3) diff --git a/day02.py b/day02.py index 6d25ff3..32bfd3b 100755 --- a/day02.py +++ b/day02.py @@ -7,7 +7,6 @@ TEST_SOLUTION_PART2 = 1 splitter = re.compile(r'([0-9]+)-([0-9]+) ([a-z]): (.*)') -@aoclib.print_execution_time def part1(test_mode=False): my_input = aoclib.getInputAsArray(day=2, test=test_mode) valid_count = 0 @@ -20,7 +19,6 @@ def part1(test_mode=False): return valid_count -@aoclib.print_execution_time def part2(test_mode=False): my_input = aoclib.getInputAsArray(day=2, test=test_mode) valid_count = 0 diff --git a/day03.py b/day03.py index f5ee381..f3adcbc 100755 --- a/day03.py +++ b/day03.py @@ -20,13 +20,11 @@ def check_for_trees(right_step, down_step, treelines): return tree_count -@aoclib.print_execution_time def part1(test_mode=False): my_input = aoclib.getInputAsArray(day=3, test=test_mode) return check_for_trees(3, 1, my_input) -@aoclib.print_execution_time def part2(test_mode=False): my_input = aoclib.getInputAsArray(day=3, test=test_mode) tree_count1 = check_for_trees(1, 1, my_input) diff --git a/day04.py b/day04.py index deee8d7..f869a15 100644 --- a/day04.py +++ b/day04.py @@ -71,7 +71,6 @@ def verifyPassportData(passport_data, verify_data=False): return True -@aoclib.print_execution_time def part1(test_mode=False): valid = 0 for passport_line in aoclib.getMultiLineInputAsArray(day=4, join_char=" ", test=test_mode): @@ -82,7 +81,6 @@ def part1(test_mode=False): return valid -@aoclib.print_execution_time def part2(test_mode=False): valid = 0 for passport_line in aoclib.getMultiLineInputAsArray(day=4, join_char=" ", test=test_mode): diff --git a/day05.py b/day05.py index f6f2fea..9d81646 100644 --- a/day05.py +++ b/day05.py @@ -44,7 +44,6 @@ def getSeatID(row, column): return row * 8 + column -@aoclib.print_execution_time def part1(test_mode=False): my_input = aoclib.getInputAsArray(day=5, test=test_mode) max_id = 0 @@ -55,7 +54,6 @@ def part1(test_mode=False): return max_id -@aoclib.print_execution_time def part2(test_mode=False): my_input = aoclib.getInputAsArray(day=5, test=test_mode) seat_list = list(range(0, 1024)) diff --git a/day06.py b/day06.py index 9d651a7..2fe8c69 100644 --- a/day06.py +++ b/day06.py @@ -14,7 +14,6 @@ def getAnswerCount(answer_line): return return_dict -@aoclib.print_execution_time def part1(test_mode=False): my_input = aoclib.getMultiLineInputAsArray(day=DAY, test=test_mode) yes_count = 0 @@ -25,7 +24,6 @@ def part1(test_mode=False): return yes_count -@aoclib.print_execution_time def part2(test_mode=False): my_input = aoclib.getMultiLineInputAsArray(day=DAY, test=test_mode) diff --git a/day07.py b/day07.py index 3de8b51..51d4279 100644 --- a/day07.py +++ b/day07.py @@ -55,7 +55,6 @@ def getBagContentCount(color_dict, my_color): return count -@aoclib.print_execution_time def part1(test_mode=False): my_input = aoclib.getInputAsArray(day=DAY, test=test_mode) possible_bags = {} @@ -71,7 +70,6 @@ def part1(test_mode=False): return len(getPossibleBagsForMyColor(possible_bags, MY_BAG)) -@aoclib.print_execution_time def part2(test_mode=False): my_input = aoclib.getInputAsArray(day=DAY, test=test_mode) big_content_dict = {} diff --git a/main.py b/main.py index 87801c0..8e95e80 100755 --- a/main.py +++ b/main.py @@ -4,11 +4,21 @@ import argparse import aoclib import importlib import os +import timeit + +TIMEIT_NUMBER = 50 argument_parser = argparse.ArgumentParser() argument_parser.add_argument("-d", "--day", help="specify day to process; leave empty for ALL days", type=int) argument_parser.add_argument("-t", "--test", help="run test cases", action="store_true", default=False) argument_parser.add_argument("-p", "--part", help="run only part x", choices=[1, 2], type=int) +argument_parser.add_argument("--timeit", help="measure execution time", action="store_true", default=False) +argument_parser.add_argument( + "--timeit-number", + help="build average time over this many executions", + type=int, + default=TIMEIT_NUMBER +) flags = argument_parser.parse_args() import_day = "" @@ -47,7 +57,23 @@ for lib in sorted(imported): ) if not flags.part or flags.part == 1: - aoclib.printSolution(day, 1, globals()[lib].part1(test_mode=flags.test), test=flags.test) + if not flags.timeit: + aoclib.printSolution(day, 1, globals()[lib].part1(test_mode=flags.test), test=flags.test) + else: + exec_time = timeit.timeit( + 'globals()[lib].part1(test_mode=flags.test)', + globals=globals(), + number=flags.timeit_number + ) / flags.timeit_number + aoclib.print_execution_time(day, 1, exec_time) if not flags.part or flags.part == 2: - aoclib.printSolution(day, 2, globals()[lib].part2(test_mode=flags.test), test=flags.test) + if not flags.timeit: + aoclib.printSolution(day, 2, globals()[lib].part2(test_mode=flags.test), test=flags.test) + else: + exec_time = timeit.timeit( + 'globals()[lib].part2(test_mode=flags.test)', + globals=globals(), + number=flags.timeit_number + ) / flags.timeit_number + aoclib.print_execution_time(day, 2, exec_time)