Created
January 29, 2016 13:44
-
-
Save therocode/cd1d2dfcbe56e120fcca to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <chrono> | |
#include <random> | |
#include <iostream> | |
std::vector<int> lotsOfNumbers(int amount, bool includeZero) | |
{ | |
std::vector<int> numbers(amount); | |
std::mt19937 random{std::random_device()()}; | |
std::uniform_int_distribution<int> intRange; | |
if(includeZero) | |
intRange = std::uniform_int_distribution<int>(0, 100000); | |
else | |
intRange = std::uniform_int_distribution<int>(1, 100000); | |
for(int i = 0; i < amount; ++i) | |
{ | |
numbers[i] = intRange(random); | |
} | |
return numbers; | |
} | |
class NumberDivider | |
{ | |
public: | |
struct DivByZero | |
{ | |
int dividend; | |
}; | |
int divideDangerous(int dividend, int divisor) | |
{ | |
return dividend / divisor; | |
} | |
int divideErrorCode(int dividend, int divisor) | |
{ | |
if(divisor != 0) | |
return dividend / divisor; | |
else | |
return -1; | |
} | |
int divideException(int dividend, int divisor) | |
{ | |
if(divisor == 0) | |
throw DivByZero{dividend}; | |
return dividend / divisor; | |
} | |
}; | |
float timeDeltaToSeconds(std::chrono::high_resolution_clock::time_point start, std::chrono::high_resolution_clock::time_point stop) | |
{ | |
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start); | |
return duration.count() / 1000.0f; | |
} | |
const int benchAmount = 100'000'000; | |
std::chrono::high_resolution_clock timer; | |
int main() | |
{ | |
NumberDivider divider; | |
std::cout << "performing benchmark on " << benchAmount << " ints\n"; | |
std::cout << "generating dividends\n"; | |
auto dividends = lotsOfNumbers(benchAmount, true); | |
std::cout << "generating safe divisors\n"; | |
auto safeDivisors = lotsOfNumbers(benchAmount, false); | |
std::cout << "generating unsafe divisors\n"; | |
auto unsafeDivisors = lotsOfNumbers(benchAmount, true); | |
std::vector<int> results(benchAmount); | |
//unsafe on safe numbers | |
std::cout << "\n"; | |
std::cout << "dividing unsafely with safe numbers...\n"; | |
auto timeStart = timer.now(); | |
for(int i = 0; i < benchAmount; ++i) | |
results[i] = divider.divideDangerous(dividends[i], safeDivisors[i]); | |
auto timeStop = timer.now(); | |
float baseline = timeDeltaToSeconds(timeStart, timeStop); | |
std::cout << "Took " << baseline << " seconds (baseline)\n"; | |
std::cout << "result is: " << std::accumulate(results.begin(), results.end(), 0) << "\n"; //to absolutely make sure no operations are optimised away | |
//error code on safe numbers | |
std::cout << "\n"; | |
std::cout << "dividing error codey with safe numbers...\n"; | |
timeStart = timer.now(); | |
for(int i = 0; i < benchAmount; ++i) | |
results[i] = divider.divideErrorCode(dividends[i], safeDivisors[i]); | |
timeStop = timer.now(); | |
float time = timeDeltaToSeconds(timeStart, timeStop); | |
std::cout << "Took " << time << " seconds (" << time/baseline << " to baseline) \n"; | |
std::cout << "result is: " << std::accumulate(results.begin(), results.end(), 0) << "\n"; //to absolutely make sure no operations are optimised away | |
//error code on unsafe numbers | |
std::cout << "\n"; | |
std::cout << "dividing error codey with unsafe numbers...\n"; | |
timeStart = timer.now(); | |
for(int i = 0; i < benchAmount; ++i) | |
results[i] = divider.divideErrorCode(dividends[i], unsafeDivisors[i]); | |
timeStop = timer.now(); | |
time = timeDeltaToSeconds(timeStart, timeStop); | |
std::cout << "Took " << time << " seconds (" << time/baseline << " to baseline) \n"; | |
std::cout << "result is: " << std::accumulate(results.begin(), results.end(), 0) << "\n"; //to absolutely make sure no operations are optimised away | |
//exception code on safe numbers | |
std::cout << "\n"; | |
std::cout << "dividing exceptiony with safe numbers...\n"; | |
timeStart = timer.now(); | |
for(int i = 0; i < benchAmount; ++i) | |
results[i] = divider.divideException(dividends[i], safeDivisors[i]); | |
timeStop = timer.now(); | |
time = timeDeltaToSeconds(timeStart, timeStop); | |
std::cout << "Took " << time << " seconds (" << time/baseline << " to baseline) \n"; | |
std::cout << "result is: " << std::accumulate(results.begin(), results.end(), 0) << "\n"; //to absolutely make sure no operations are optimised away | |
//exception code on unsafe numbers | |
std::cout << "\n"; | |
std::cout << "dividing exceptiony with unsafe numbers...\n"; | |
timeStart = timer.now(); | |
for(int i = 0; i < benchAmount; ++i) | |
{ | |
try | |
{ | |
results[i] = divider.divideException(dividends[i], unsafeDivisors[i]); | |
} | |
catch(NumberDivider::DivByZero& e) | |
{ | |
} | |
} | |
timeStop = timer.now(); | |
time = timeDeltaToSeconds(timeStart, timeStop); | |
std::cout << "Took " << time << " seconds (" << time/baseline << " to baseline) \n"; | |
std::cout << "result is: " << std::accumulate(results.begin(), results.end(), 0) << "\n"; //to absolutely make sure no operations are optimised away | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment