//ProjectEulerCPP/benchmark.hpp //Mattrixwv // 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 #ifndef BENCHMARK_HPP #define BENCHMARK_HPP #include #include #include "ProblemSelection.hpp" void printBenchmarkMenu(); //Prints the menu to the screen 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 enum BENCHMARK_OPTIONS {RUN_SPECIFIC = 1, RUN_ALL_SHORT, RUN_ALL, BENCHMARK_EXIT, BENCHMARK_SIZE}; std::vector tooLong = {15}; void benchmarkMenu(){ int selection = 0; printBenchmarkMenu(); selection = getBenchmarkMenuSelection(); switch(selection){ case BENCHMARK_OPTIONS::RUN_SPECIFIC: runSpecific(); break; case BENCHMARK_OPTIONS::RUN_ALL_SHORT: runAllShort(); break; case BENCHMARK_OPTIONS::RUN_ALL: runAll(); break; case BENCHMARK_OPTIONS::BENCHMARK_EXIT: break; } } void printBenchmarkMenu(){ std::cout << "1. Run a specific problem\n" << "2. Run all problems that have a reasonably short run time\n" << "3. Run all problems\n" << "4. Exit the menu" << std::endl; } int getBenchmarkMenuSelection(){ int selection = 0; std::cin >> selection; while(std::cin.fail() || !isValidBenchmarkMenu(selection)){ std::cout << "That is an invalid option!\nPress Enter to continue" << std::endl; std::cin.clear(); std::cin.get(); printBenchmarkMenu(); std::cin >> selection; } return selection; } bool isValidBenchmarkMenu(int selection){ if((selection > 0) && (selection < BENCHMARK_OPTIONS::BENCHMARK_SIZE)){ return true; } else{ return false; } } 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 Problem* problem = getProblem(problemNumber); //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); //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; } 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 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); //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; } } 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); //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; } } unsigned int getNumberOfTimesToRun(){ unsigned int numOfTimesToRun = 1; std::cout << "How many times do you want to run this problem? "; std::cin >> numOfTimesToRun; while((std::cin.fail()) || (numOfTimesToRun < 1)){ std::cout << "That is an invalid number!\nHow many times do you want to run this problem? "; std::cin.clear(); std::cin >> numOfTimesToRun; } return numOfTimesToRun; } #endif //BENCHMARK_HPP