I'm creating a library in C++ which has a class with statistical test methods. I also want to write another class that has a set of performance tests over it (like time taken to do a test), but I wonder if I'm doing this the right way, for best performance and reusability.
I have class with the statistical methods (uniformnistanalysis.cpp), a class that is the "test environment" that encapsulates and calls those statistical tests (performance.cpp) with a number n of runs, and checks for the execution time of the function. I want to implement more performance tests but I want first to be sure that the code architecture is fine and hear about other possible arrangements.
Note: performance has an inner class called Timer that counts the execution time of the function for n runs, but as n increases, the average time decreases considerably - and shouldn't, since I'm taking the average of the time of N-runs for the function and then dividing by n. It's going from ~350ns (for n=1) to ~35ns (for n=1000000)
My code structure is:
uniformnistanalysis:
class UniformNISTAnalysis {
public:
bool monobit(const DynamicBitset&, double = 0.1);
}
performance.hpp:
class Performance {
public:
void testMonobit(UniformNISTAnalysis&, const DynamicBitset&, const size_t);
// more tests will be here...
protected:
class Timer {
public:
Timer(const std::string&, size_t);
~Timer();
private:
std::string functionName;
size_t runs;
std::chrono::steady_clock::time_point start;
};
}
parts of performance.cpp:
void TestEnvironment::testMonobit(UniformNISTAnalysis& analysis, const DynamicBitset& bitset, const size_t runs = 1) {
printTestHeader("Monobit [Mon]");
bool status;
// print result
std::cout << "Number: " << bitset << std::endl;
std::cout << "Ones: " << bitset.countOnes() << "; Zeroes: " << bitset.countZeroes() << std::endl;
std::cout << "Ratio of 1s: " << bitset.countOnes() / static_cast<double>(bitset.numBits) << std::endl;
{
Timer timer("Monobit", runs);
for(size_t i = 0; i < runs; i++)
status = analysis.monobit(bitset);
}
printTestStatus("Monobit", status);
}
TestEnvironment::Timer::Timer(const std::string& name, const size_t runs = 1) : functionName(name), runs(runs) {
start = std::chrono::steady_clock::now();
}
TestEnvironment::Timer::~Timer() {
auto stop = std::chrono::steady_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(stop - start);
std::cout << runs << " test(s) '" << functionName << "' took an average of " << duration.count() / static_cast<double>(runs) << "ns to execute." << std::endl;
}
Calling example:
Performance testEnv;
UniformNISTAnalysis analysis;
testEnv.testMonobit(analysis, bitset, 100000);
Aucun commentaire:
Enregistrer un commentaire