Last active
April 27, 2024 13:59
-
-
Save bwedding/fe6c4e5429988455721ac580ac78ddca to your computer and use it in GitHub Desktop.
1000 random tasks
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 <iostream> | |
#include <vector> | |
#include <algorithm> | |
#include <numeric> | |
#include <random> | |
#include <functional> | |
#include <chrono> | |
using namespace std::chrono; | |
constexpr size_t N = 1000; | |
constexpr size_t OPSTODO = 50000; | |
template<typename Func> | |
struct Callables { | |
std::vector<Func> functions; | |
void add(Func func) | |
{ | |
functions.push_back(func); | |
} | |
void rearrange(const std::vector<size_t>& order) | |
{ | |
if (order.size() != functions.size()) | |
{ | |
throw std::invalid_argument("Order vector size must match functions vector size."); | |
} | |
std::vector<Func> rearranged_functions(functions.size()); | |
for (size_t i = 0; i < order.size(); ++i) | |
{ | |
if (order[i] >= functions.size()) | |
{ | |
throw std::out_of_range("Order index out of range."); | |
} | |
rearranged_functions[i] = functions[order[i]]; | |
} | |
functions = rearranged_functions; | |
} | |
void callAll(int arg, std::vector<size_t>& order, bool print) | |
{ | |
for (const auto& func : order) | |
{ | |
functions[func](arg); | |
if (print) | |
{ | |
std::cout << arg << std::endl; | |
} | |
} | |
} | |
void callAll(int arg, bool print) | |
{ | |
for (const auto& func : functions) | |
{ | |
func(arg); | |
if (print) | |
{ | |
std::cout << arg << std::endl; | |
} | |
} | |
} | |
}; | |
class ExecutionTimer | |
{ | |
public: | |
// Use the best steady clock available | |
using Clock = std::conditional_t<high_resolution_clock::is_steady, | |
high_resolution_clock, | |
steady_clock>; | |
ExecutionTimer() = default; | |
inline ~ExecutionTimer() | |
{ | |
std::string units = " microSeconds"; | |
// Determine whether to print uSecs or mSecs or Secs | |
double count = duration_cast<microseconds>(Clock::now() - mStart).count(); | |
if (count > 1000) | |
{ | |
// Convert to milliseconds | |
units = " milliSeconds"; | |
count /= 1000.0f; | |
if (count > 1000) | |
{ | |
// Convert to seconds | |
units = " Seconds"; | |
count /= 1000.0f; | |
} | |
} | |
std::cout | |
<< "Elapsed: " << count << units.data() << std::endl; | |
} | |
private: | |
Clock::time_point mStart = Clock::now(); | |
}; | |
std::vector<size_t> GenerateRandomOrder(size_t n) | |
{ | |
std::vector<size_t> vec(n); | |
std::iota(vec.begin(), vec.end(), 0); | |
std::random_device rd; | |
std::mt19937 g(rd()); | |
std::shuffle(vec.begin(), vec.end(), g); | |
return vec; | |
} | |
void makeOperations(Callables<std::function<void(int&)>> &callables) | |
{ | |
std::random_device rd; | |
std::mt19937 gen(rd()); | |
std::uniform_int_distribution<> operation_dist(0, 4); // 0: add, 1: subtract, 2: multiply, 3: divide 4: negate | |
std::uniform_int_distribution<> value_dist(1, 100); | |
for (int i = 0; i < N; ++i) | |
{ | |
int operation_type = operation_dist(gen); | |
int value = value_dist(gen); | |
switch (operation_type) | |
{ | |
case 0: | |
// Addition | |
callables.add([value](int& x) { x += value; }); | |
break; | |
case 1: | |
// Subtraction | |
callables.add([value](int& x) { x -= value; }); | |
break; | |
case 2: | |
// Multiplication | |
callables.add([value](int& x) { x *= value; }); | |
break; | |
case 3: | |
// Division | |
callables.add([value](int& x) | |
{ | |
if (value != 0) | |
{ | |
x /= value; | |
} | |
}); | |
break; | |
case 4: | |
// Negation | |
callables.add([value](int& x) { x = -x; }); | |
break; | |
} | |
} | |
} | |
int main() | |
{ | |
auto order = GenerateRandomOrder(N); | |
Callables<std::function<void(int&)>> callables; | |
makeOperations(callables); | |
std::random_device rd; | |
std::mt19937 gen(rd()); | |
std::uniform_int_distribution<> value_dist(2, 1000); | |
std::cout << "Starting Arranged" << std::endl; | |
{ | |
callables.rearrange(order); | |
ExecutionTimer timer; | |
for (int i = 0; i < OPSTODO; ++i) | |
{ | |
int input = value_dist(gen); | |
callables.callAll(input, false); | |
} | |
} | |
std::cout << "Finished" << std::endl; | |
std::cout << "Starting Unarranged" << std::endl; | |
{ | |
ExecutionTimer timer; | |
for (int i = 0; i < OPSTODO; ++i) | |
{ | |
int input = value_dist(gen); | |
callables.callAll(input, order, false); | |
} | |
} | |
std::cout << "Finished" << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment