import subprocess from random import randint from time import time, sleep import matplotlib.pyplot as plt def run_benchmark(program_name, array): start = time() process = subprocess.Popen(program_name, stdin=subprocess.PIPE) process.communicate((f"{len(array)}\n" + "\n".join(map(str, array))).encode()) if process.returncode == 1: raise RuntimeError("Error while benchmarking") end = time() return end - start def generate_sequence(sequence_type, array_size): if sequence_type == "random": return [randint(0, 100) for i in range(array_size)] elif sequence_type == "sorted": return [i for i in range(array_size)] elif sequence_type == "reversed": return [i for i in range(array_size, 0, -1)] elif sequence_type == "constant": return [5 for i in range(array_size)] elif sequence_type == "v_shaped": return [i for i in range(array_size//2, 0, -1)]+[i for i in range(array_size//2)] else: raise ValueError("Invalid sequence type") def plot(program_name, sequences, array_size): sequence_names = { "random": "Losowy", "sorted": "Posortowany", "reversed": "Odwrócony", "constant": "Stały", "v_shaped": "V-kształtny", } plt.figure(figsize=(10, 6)) for sequence_type, timings in sequences.items(): plt.plot(array_size, timings, label=sequence_names[sequence_type]) plt.xlabel("Rozmiar tablicy") plt.ylabel("Czas (ms)") plt.title(program_name.capitalize()) plt.legend() plt.savefig(f"./benchmarks/{program_name}.png") if __name__ == "__main__": program_names = ["insertion", "selection", "heapsort", "mergesort"] sequence_types = ["random", "sorted", "reversed", "constant", "v_shaped"] array_sizes = [i for i in range(1000, 15001, 1000)] tests = 10 with open("results.txt", "w") as f: for program_name in program_names: if program_name == "heapsort" or program_name == "mergesort": array_sizes = [i for i in range(15000, 40001, 1000)] tests = 20 else: array_sizes = [i for i in range(1000, 15001, 1000)] tests = 10 sequenceTiming = { "random": [], "sorted": [], "reversed": [], "constant": [], "v_shaped": [] } print(f"Running {program_name}") for sequence_type in sequence_types: print(f" - running {sequence_type}") for array_size in array_sizes: sequence = generate_sequence(sequence_type, array_size) durations = [] for i in range(tests): print(f" - running {sequence_type} with size {array_size} {i+1}/{tests}", end="\r") duration = run_benchmark(f"./dist/{program_name}", sequence) duration *= 1000 durations.append(duration) if program_name == "heapsort" or program_name == "mergesort": sleep(0.1) print() duration = sum(durations) / len(durations) sequenceTiming[sequence_type].append(duration) if program_name == "heapsort" or program_name == "mergesort": sleep(0.1) plot(program_name, sequenceTiming, array_sizes) print("Benchmark finished")