-
-
Save JSzitas/921726d1a91320991b19331465a1f06e to your computer and use it in GitHub Desktop.
Count how many people are alive per year, based on their birthyear and deathyear
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 <iostream> | |
#include <vector> | |
constexpr size_t kPeople = 10000; | |
constexpr size_t kLowBoundAge = 1; | |
constexpr size_t kHighBoundAge = 100; | |
constexpr size_t kAgeLen = kHighBoundAge - kLowBoundAge; | |
int main() | |
{ | |
// do not benchmark creation of test data - the other implementation does not do this | |
// either | |
static_assert(kAgeLen < RAND_MAX); | |
// use size_t to avoid annoying signed integer compare warnings | |
size_t personBirthday[kPeople] = {}; | |
size_t personDeath[kPeople] = {}; | |
// Filling | |
for (size_t i = 0; i < kPeople; ++i) | |
{ | |
personBirthday[i] = 1900 + rand() % (1 + 2000 - 1900); | |
personDeath[i] = personBirthday[i] + kLowBoundAge + rand() % (kAgeLen + 1); | |
} | |
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); | |
//mark out the years - which we understand to be a continguous block - | |
// and we add to the population over those years - addition over a continguous | |
// vector is much faster than a map - we also know the size ahead of time | |
// but std::array should not be very different, both offer continguous storage | |
std::vector<int> population(100,0); | |
// this makes more sense for the problem at hand, as the years must be, | |
// by design, a continguous sequence (a person cannot be alive, then dead, | |
// then alive again...) | |
constexpr size_t kNumberRepeats = 100; | |
for (size_t r = 0; r < kNumberRepeats; r++) | |
{ | |
// reset contents of population vector | |
std::fill(population.begin(), population.end(), 0); | |
for (size_t i = 0; i < kPeople; i++) | |
{ | |
for (size_t year = personBirthday[i]; year < personDeath[i]; year++) | |
{ | |
population[year] += 1; | |
} | |
} | |
} | |
// we should not benchmark the time it takes us to print the output - the other benchmarked version is not doing that | |
// either | |
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); | |
std::cout << "Time difference = " << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() << " [milliseconds]" << std::endl; | |
return 0; | |
} | |
// for this I get a timing of roughly 20 milliseconds, or 0.02 seconds | |
// again, compile with | |
// g++ -O3 -DNDEBUG -std=c++17 test.cpp -o my_app | |
// but using clang++ I get the same timings, so likely leads to same code |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment