Reputation: 1909
I am using the following to time my unit tests:
template<typename F>
void TestFunc(F lambda)
{
std::array<std::chrono::milliseconds::rep, 20> time;
for (int i = 0; i < 10; ++i) {
auto t1 = std::chrono::high_resolution_clock::now();
for (int j = 0; j < 1000; ++j) {
lambda();
}
auto t2 = std::chrono::high_resolution_clock::now();
time[i] = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count();
}
size_t avg = std::accumulate(begin(time), end(time), (std::chrono::milliseconds::rep)0) / time.size();
...
}
But I am getting corrupted results on ubuntu + gcc 4.9.2. Values like 21006482932417 where gcc 4.8 and VS2013 are returning 4 ms
Before updating gcc from 4.8.x to 4.9.2, the measurement were corrects. Could it be than an incorrect version of libstd has been used ? I ran ldd to check
> ldd ./bin/unittest
linux-vdso.so.1 => (0x00007fff039fe000)
libboost_chrono.so.1.57.0 => /usr/local/lib/libboost_chrono.so.1.57.0 (0x00007fde053c2000)
libboost_system.so.1.57.0 => /usr/local/lib/libboost_system.so.1.57.0 (0x00007fde051bd000)
libboost_filesystem.so.1.57.0 => /usr/local/lib/libboost_filesystem.so.1.57.0 (0x00007fde04fa6000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fde04d7c000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fde04a6f000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fde04858000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fde04492000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fde04289000)
/lib64/ld-linux-x86-64.so.2 (0x00007fde057f7000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fde03f83000)
Also tried switching to boost::chrono but it didn't help either. What could be the possible cause ?
Upvotes: 2
Views: 423
Reputation: 4925
You're allocating an array of 20 items, but only assigning values to the first 10, so the rest are unitialized. Even if they were initialized to 0 they'd throw off the average calculation. You might do something like this where you pass in the number of times to run the test so the sizes don't get out of sync.
#include <algorithm>
#include <array>
#include <chrono>
#include <functional>
#include <iostream>
#include <numeric>
#include <vector>
template <size_t N, typename F>
void TestFunc(F lambda)
{
std::array<std::chrono::milliseconds::rep, N> time;
for(int i = 0; i < N; ++i)
{
auto t1 = std::chrono::high_resolution_clock::now();
for(int j = 0; j < 1000; ++j)
{
lambda();
}
auto t2 = std::chrono::high_resolution_clock::now();
time[i] = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count();
}
auto avg = std::accumulate(begin(time), end(time), (std::chrono::milliseconds::rep)0) / time.size();
std::cout << "Average of " << N << " tests is " << avg << "ms.\n";
}
int main()
{
std::function<int()> f = []()
{
int sum = 0; for(int i = 0; i < 100000; ++i) sum += i; return sum;
};
TestFunc<10>(f);
return 0;
}
I don't have gcc 4.9.2 handy to test with, but this worked well in Visual Studio 2013 and on ideone.
Upvotes: 1