diff --git a/benchmark.hpp b/benchmark.hpp
index 31881ff..9b6dcb8 100644
--- a/benchmark.hpp
+++ b/benchmark.hpp
@@ -1,8 +1,24 @@
-//ProjectEulerCPP/benchmark.hpp
-//Mattrixwv
+//ProjectEuler/ProjectEulerCPP/benchmark.hpp
+//Matthew Ellison
// Created: 07-08-20
-//Modified: 07-08-20
-//This is a program that runs a problem several times to get the average time it takes to run
+//Modified: 07-09-20
+//These are functions that help determine an average run time for the problems
+/*
+ Copyright (C) 2020 Matthew Ellison
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+*/
#ifndef BENCHMARK_HPP
@@ -13,18 +29,23 @@
#include "ProblemSelection.hpp"
-void printBenchmarkMenu(); //Prints the menu to the screen
+void printBenchmarkMenu(); //Print the benchmark menu
int getBenchmarkMenuSelection(); //Returns a valid menu option
bool isValidBenchmarkMenu(int selection); //Determines if a value is a valid menu option. Helper for getBenchmarkMenuSelection
void runSpecific(); //Determines which problem user wants to run and runs it
void runAllShort(); //Runs all problems except a few that are specified because of run length
void runAll(); //Runs all problems
unsigned int getNumberOfTimesToRun(); //Asks how many times a problem is supposed to run and returns the value
+double runProblem(Problem* problem, unsigned int timesToRun); //Runs the problem the given number of times
+std::string getBenchmarkResults(Problem* problem, double totalTime, unsigned int timesRan); //Prints the benchmark results of a problem
+//Variables
+//Valid menu options
enum BENCHMARK_OPTIONS {RUN_SPECIFIC = 1, RUN_ALL_SHORT, RUN_ALL, BENCHMARK_EXIT, BENCHMARK_SIZE};
-std::vector tooLong = {15};
+std::vector tooLong = {15}; //The list of problems that take "too long" to run. (Over 1 second on my machine)
+//The driver function for the benchmark selection
void benchmarkMenu(){
int selection = 0;
@@ -39,6 +60,7 @@ void benchmarkMenu(){
}
}
+//Print the benchmark menu
void printBenchmarkMenu(){
std::cout << "1. Run a specific problem\n"
<< "2. Run all problems that have a reasonably short run time\n"
@@ -46,6 +68,7 @@ void printBenchmarkMenu(){
<< "4. Exit the menu" << std::endl;
}
+//Returns a valid menu option
int getBenchmarkMenuSelection(){
int selection = 0;
std::cin >> selection;
@@ -59,6 +82,7 @@ int getBenchmarkMenuSelection(){
return selection;
}
+//Determines if a value is a valid menu option. Helper for getBenchmarkMenuSelection
bool isValidBenchmarkMenu(int selection){
if((selection > 0) && (selection < BENCHMARK_OPTIONS::BENCHMARK_SIZE)){
return true;
@@ -68,96 +92,79 @@ bool isValidBenchmarkMenu(int selection){
}
}
+//Determines which problem user wants to run and runs it
void runSpecific(){
- double totalTime = 0;
//Ask which problem the user wants to run
unsigned int problemNumber = getProblemNumber();
//Ask how many times to run the problem
unsigned int timesToRun = getNumberOfTimesToRun();
- //Get the problem
+
+ //Get the problem and print its description
Problem* problem = getProblem(problemNumber);
+ std::cout << problemNumber << ". " << problem->getDescription() << '\n';
+
//Run the problem the specific number of times
- std::cout << problemNumber << ". " << problem->getDescription()
- << "\nSolving";
- for(unsigned int cnt = 0;cnt < timesToRun;++cnt){
- //Reset the data so you are actually counting the run time a second time
- problem->reset();
- (std::cout << '.').flush();
- //Solve the problem
- problem->solve();
- //Get the time data
- totalTime += problem->getTimer().getNano();
- }
- //Calculate the average run time
- totalTime /= timesToRun;
- std::string timeResults = mee::Stopwatch::getStr(totalTime);
+ double totalTime = runProblem(problem, timesToRun);
+
//Print the results
- std::cout << "\n\n" << problem->getString();
- std::cout << "\nIt took an average of " << timeResults << " to run this problem through " << timesToRun << " iterations\n\n" << std::endl;
+ std::cout << getBenchmarkResults(problem, totalTime, timesToRun);
+
+ //Release the memory the problem is in
+ delete problem;
}
+//Runs all problems except a few that are specified because of run length
void runAllShort(){
//Ask how many times to run the problem
unsigned int timesToRun = getNumberOfTimesToRun();
+
//Run through all valid problem numbers, skipping a few that are in the tooLong vector
for(unsigned int cnt = 1;cnt < PROBLEM_NUMBERS.size();++cnt){
unsigned int problemNumber = PROBLEM_NUMBERS[cnt];
- double totalTime = 0;
//If the problem number is contained in the list of problems that take too long skip it
if(mee::isFound(tooLong, problemNumber)){
continue;
}
- //Get the problem
+
+ //Get the problem and print its description
Problem* problem = getProblem(problemNumber);
- //Run each problem the specified number of times
- std::cout << problemNumber << ". " << problem->getDescription()
- << "\nSolving";
- for(unsigned int cnt = 0;cnt < timesToRun;++cnt){
- //Reset the data so you are actually counting the run time a second time
- problem->reset();
- (std::cout << '.').flush();
- //Solve the problem
- problem->solve();
- //Get the time data
- totalTime += (problem->getTimer()).getNano();
- }
- //Calculate the average run time of the problem
- totalTime /= timesToRun;
- std::string timeResults = mee::Stopwatch::getStr(totalTime);
+ std::cout << problemNumber << ". " << problem->getDescription() << '\n';
+
+ //Run the problem the specified number of times
+ double totalTime = runProblem(problem, timesToRun);
+
//Print the results
- std::cout << "\n\n" << problem->getString();
- std::cout << "\nIt took an average of " << timeResults << " to run this problem over " << timesToRun << " iterations\n\n" << std::endl;
+ std::cout << getBenchmarkResults(problem, totalTime, timesToRun);
+
+ //Release the memory the problem is in
+ delete problem;
}
}
+//Runs all problems
void runAll(){
//Ask how many times to run the problem
unsigned int timesToRun = getNumberOfTimesToRun();
+
//Run through all valid problem numbers, skipping a few that are in the tooLong vector
for(unsigned int cnt = 1;cnt < PROBLEM_NUMBERS.size();++cnt){
unsigned int problemNumber = PROBLEM_NUMBERS[cnt];
double totalTime = 0;
+
//Get the problem
Problem* problem = getProblem(problemNumber);
- //Run each problem the specified number of times
- std::cout << problemNumber << ". " << problem->getDescription()
- << "\nSolving";
- for(unsigned int cnt = 0;cnt < timesToRun;++cnt){
- //Reset the data so you are actually counting the run time a second time
- problem->reset();
- (std::cout << '.').flush();
- //Solve the problem
- problem->solve();
- //Get the time data
- totalTime += (problem->getTimer()).getNano();
- }
- //Calculate the average run time of the problem
- totalTime /= timesToRun;
- std::string timeResults = mee::Stopwatch::getStr(totalTime);
+
+ //Run the problem the specified number of times
+ std::cout << problemNumber << ". " << problem->getDescription() << '\n';
+ runProblem(problem, timesToRun);
+
//Print the results
- std::cout << "\n\n" << problem->getString();
- std::cout << "\nIt took an average of " << timeResults << " to run this problem over " << timesToRun << " iterations\n\n" << std::endl;
+ std::cout << getBenchmarkResults(problem, totalTime, timesToRun);
+
+ //Release the memory the problem is in
+ delete problem;
}
}
+//Asks how many times a problem is supposed to run and returns the value
unsigned int getNumberOfTimesToRun(){
unsigned int numOfTimesToRun = 1;
std::cout << "How many times do you want to run this problem? ";
@@ -170,4 +177,33 @@ unsigned int getNumberOfTimesToRun(){
return numOfTimesToRun;
}
+//Runs the problem the given number of times
+double runProblem(Problem* problem, unsigned int timesToRun){
+ double totalTime = 0;
+ std::cout << "Solving";
+ for(unsigned int cnt = 0;cnt < timesToRun;++cnt){
+ //Reset the data so you are actually counting the run time a second time
+ problem->reset();
+ (std::cout << '.').flush();
+ //Solve the problem
+ problem->solve();
+ //Get the time data
+ totalTime += (problem->getTimer()).getNano();
+ }
+ return totalTime;
+}
+
+//Prints the benchmark results of a problem
+std::string getBenchmarkResults(Problem* problem, double totalTime, unsigned int timesRan){
+ //Calculate the average run time of the problem
+ totalTime /= timesRan;
+ std::string timeResults = mee::Stopwatch::getStr(totalTime);
+ //Tally the results
+ std::stringstream results;
+ results << "\n\n" << problem->getString();
+ results << "\nIt took an average of " << timeResults << " to run this problem over " << timesRan << " iterations\n\n" << std::endl;
+ return results.str();
+}
+
+
#endif //BENCHMARK_HPP