mirror of
https://bitbucket.org/Mattrixwv/projecteulercpp.git
synced 2025-12-06 17:13:59 -05:00
Created some functions to reduce amount of copied code
Updated comments
This commit is contained in:
156
benchmark.hpp
156
benchmark.hpp
@@ -1,8 +1,24 @@
|
|||||||
//ProjectEulerCPP/benchmark.hpp
|
//ProjectEuler/ProjectEulerCPP/benchmark.hpp
|
||||||
//Mattrixwv
|
//Matthew Ellison
|
||||||
// Created: 07-08-20
|
// Created: 07-08-20
|
||||||
//Modified: 07-08-20
|
//Modified: 07-09-20
|
||||||
//This is a program that runs a problem several times to get the average time it takes to run
|
//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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef BENCHMARK_HPP
|
#ifndef BENCHMARK_HPP
|
||||||
@@ -13,18 +29,23 @@
|
|||||||
#include "ProblemSelection.hpp"
|
#include "ProblemSelection.hpp"
|
||||||
|
|
||||||
|
|
||||||
void printBenchmarkMenu(); //Prints the menu to the screen
|
void printBenchmarkMenu(); //Print the benchmark menu
|
||||||
int getBenchmarkMenuSelection(); //Returns a valid menu option
|
int getBenchmarkMenuSelection(); //Returns a valid menu option
|
||||||
bool isValidBenchmarkMenu(int selection); //Determines if a value is a valid menu option. Helper for getBenchmarkMenuSelection
|
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 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 runAllShort(); //Runs all problems except a few that are specified because of run length
|
||||||
void runAll(); //Runs all problems
|
void runAll(); //Runs all problems
|
||||||
unsigned int getNumberOfTimesToRun(); //Asks how many times a problem is supposed to run and returns the value
|
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};
|
enum BENCHMARK_OPTIONS {RUN_SPECIFIC = 1, RUN_ALL_SHORT, RUN_ALL, BENCHMARK_EXIT, BENCHMARK_SIZE};
|
||||||
std::vector<unsigned int> tooLong = {15};
|
std::vector<unsigned int> 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(){
|
void benchmarkMenu(){
|
||||||
int selection = 0;
|
int selection = 0;
|
||||||
|
|
||||||
@@ -39,6 +60,7 @@ void benchmarkMenu(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Print the benchmark menu
|
||||||
void printBenchmarkMenu(){
|
void printBenchmarkMenu(){
|
||||||
std::cout << "1. Run a specific problem\n"
|
std::cout << "1. Run a specific problem\n"
|
||||||
<< "2. Run all problems that have a reasonably short run time\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;
|
<< "4. Exit the menu" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Returns a valid menu option
|
||||||
int getBenchmarkMenuSelection(){
|
int getBenchmarkMenuSelection(){
|
||||||
int selection = 0;
|
int selection = 0;
|
||||||
std::cin >> selection;
|
std::cin >> selection;
|
||||||
@@ -59,6 +82,7 @@ int getBenchmarkMenuSelection(){
|
|||||||
return selection;
|
return selection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Determines if a value is a valid menu option. Helper for getBenchmarkMenuSelection
|
||||||
bool isValidBenchmarkMenu(int selection){
|
bool isValidBenchmarkMenu(int selection){
|
||||||
if((selection > 0) && (selection < BENCHMARK_OPTIONS::BENCHMARK_SIZE)){
|
if((selection > 0) && (selection < BENCHMARK_OPTIONS::BENCHMARK_SIZE)){
|
||||||
return true;
|
return true;
|
||||||
@@ -68,96 +92,79 @@ bool isValidBenchmarkMenu(int selection){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Determines which problem user wants to run and runs it
|
||||||
void runSpecific(){
|
void runSpecific(){
|
||||||
double totalTime = 0;
|
|
||||||
//Ask which problem the user wants to run
|
//Ask which problem the user wants to run
|
||||||
unsigned int problemNumber = getProblemNumber();
|
unsigned int problemNumber = getProblemNumber();
|
||||||
//Ask how many times to run the problem
|
//Ask how many times to run the problem
|
||||||
unsigned int timesToRun = getNumberOfTimesToRun();
|
unsigned int timesToRun = getNumberOfTimesToRun();
|
||||||
//Get the problem
|
|
||||||
|
//Get the problem and print its description
|
||||||
Problem* problem = getProblem(problemNumber);
|
Problem* problem = getProblem(problemNumber);
|
||||||
|
std::cout << problemNumber << ". " << problem->getDescription() << '\n';
|
||||||
|
|
||||||
//Run the problem the specific number of times
|
//Run the problem the specific number of times
|
||||||
std::cout << problemNumber << ". " << problem->getDescription()
|
double totalTime = runProblem(problem, timesToRun);
|
||||||
<< "\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);
|
|
||||||
//Print the results
|
//Print the results
|
||||||
std::cout << "\n\n" << problem->getString();
|
std::cout << getBenchmarkResults(problem, totalTime, timesToRun);
|
||||||
std::cout << "\nIt took an average of " << timeResults << " to run this problem through " << timesToRun << " iterations\n\n" << std::endl;
|
|
||||||
|
//Release the memory the problem is in
|
||||||
|
delete problem;
|
||||||
}
|
}
|
||||||
|
//Runs all problems except a few that are specified because of run length
|
||||||
void runAllShort(){
|
void runAllShort(){
|
||||||
//Ask how many times to run the problem
|
//Ask how many times to run the problem
|
||||||
unsigned int timesToRun = getNumberOfTimesToRun();
|
unsigned int timesToRun = getNumberOfTimesToRun();
|
||||||
|
|
||||||
//Run through all valid problem numbers, skipping a few that are in the tooLong vector
|
//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){
|
for(unsigned int cnt = 1;cnt < PROBLEM_NUMBERS.size();++cnt){
|
||||||
unsigned int problemNumber = PROBLEM_NUMBERS[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 the problem number is contained in the list of problems that take too long skip it
|
||||||
if(mee::isFound(tooLong, problemNumber)){
|
if(mee::isFound(tooLong, problemNumber)){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//Get the problem
|
|
||||||
|
//Get the problem and print its description
|
||||||
Problem* problem = getProblem(problemNumber);
|
Problem* problem = getProblem(problemNumber);
|
||||||
//Run each problem the specified number of times
|
std::cout << problemNumber << ". " << problem->getDescription() << '\n';
|
||||||
std::cout << problemNumber << ". " << problem->getDescription()
|
|
||||||
<< "\nSolving";
|
//Run the problem the specified number of times
|
||||||
for(unsigned int cnt = 0;cnt < timesToRun;++cnt){
|
double totalTime = runProblem(problem, timesToRun);
|
||||||
//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);
|
|
||||||
//Print the results
|
//Print the results
|
||||||
std::cout << "\n\n" << problem->getString();
|
std::cout << getBenchmarkResults(problem, totalTime, timesToRun);
|
||||||
std::cout << "\nIt took an average of " << timeResults << " to run this problem over " << timesToRun << " iterations\n\n" << std::endl;
|
|
||||||
|
//Release the memory the problem is in
|
||||||
|
delete problem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//Runs all problems
|
||||||
void runAll(){
|
void runAll(){
|
||||||
//Ask how many times to run the problem
|
//Ask how many times to run the problem
|
||||||
unsigned int timesToRun = getNumberOfTimesToRun();
|
unsigned int timesToRun = getNumberOfTimesToRun();
|
||||||
|
|
||||||
//Run through all valid problem numbers, skipping a few that are in the tooLong vector
|
//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){
|
for(unsigned int cnt = 1;cnt < PROBLEM_NUMBERS.size();++cnt){
|
||||||
unsigned int problemNumber = PROBLEM_NUMBERS[cnt];
|
unsigned int problemNumber = PROBLEM_NUMBERS[cnt];
|
||||||
double totalTime = 0;
|
double totalTime = 0;
|
||||||
|
|
||||||
//Get the problem
|
//Get the problem
|
||||||
Problem* problem = getProblem(problemNumber);
|
Problem* problem = getProblem(problemNumber);
|
||||||
//Run each problem the specified number of times
|
|
||||||
std::cout << problemNumber << ". " << problem->getDescription()
|
//Run the problem the specified number of times
|
||||||
<< "\nSolving";
|
std::cout << problemNumber << ". " << problem->getDescription() << '\n';
|
||||||
for(unsigned int cnt = 0;cnt < timesToRun;++cnt){
|
runProblem(problem, timesToRun);
|
||||||
//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);
|
|
||||||
//Print the results
|
//Print the results
|
||||||
std::cout << "\n\n" << problem->getString();
|
std::cout << getBenchmarkResults(problem, totalTime, timesToRun);
|
||||||
std::cout << "\nIt took an average of " << timeResults << " to run this problem over " << timesToRun << " iterations\n\n" << std::endl;
|
|
||||||
|
//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 getNumberOfTimesToRun(){
|
||||||
unsigned int numOfTimesToRun = 1;
|
unsigned int numOfTimesToRun = 1;
|
||||||
std::cout << "How many times do you want to run this problem? ";
|
std::cout << "How many times do you want to run this problem? ";
|
||||||
@@ -170,4 +177,33 @@ unsigned int getNumberOfTimesToRun(){
|
|||||||
return numOfTimesToRun;
|
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
|
#endif //BENCHMARK_HPP
|
||||||
|
|||||||
Reference in New Issue
Block a user