The class below will be used to track the execution time of various operations. There is no need to dip into C libraries to get formatted output then.
Output would be something like this:
- 10 seconds 345 milliseconds 324 microseconds
- 23 hours 32 minutes 15 seconds 324 milliseconds
It depends on the class initialization units and time passed. My query is whether any improvement is possible on this design or this good enough to be used widely. There are dummy parameters in the various diff_str
private functions to enable overloading since seconds::rep
and microseconds::rep
essentially boils down to same basic types and so one for other pairs. I have done this on VS 2013.
#include <chrono>
#include <iostream>
template<typename clock_type, typename dur>
class ExecutionTimer
{
private:
typename clock_type::time_point m_start;
typename clock_type::time_point m_end;
const std::wstring SS = std::wstring(L" ");
public:
void set_start(){
m_start = clock_type::now();
}
void set_start(typename clock_type::time_point start){
m_start = start;
}
void set_end(){
m_end = clock_type::now();
}
void set_end(typename clock_type::time_point end){
m_end = end;
}
typename dur::rep diff()
{
return std::chrono::duration_cast<dur>(m_end - m_start).count();
};
std::wstring diff_str()
{
auto ret = diff_str(diff(), std::chrono::duration_cast<dur>(std::chrono::seconds(1)));
return ret;
}
private:
std::wstring
diff_str(std::chrono::hours::rep value, std::chrono::hours dummy)
{
using namespace std::chrono;
auto ret = std::to_wstring(value) + SS + L"hours";
return ret;
}
std::wstring
diff_str(std::chrono::minutes::rep value, std::chrono::minutes dummy)
{
using namespace std::chrono;
std::wstring ret{ L"" };
auto cmp_unit = minutes(60).count();
auto dummy_to_pass = duration_cast<hours>(dummy);
if (value > cmp_unit){
ret = diff_str(hours::rep(value / cmp_unit), dummy_to_pass);
ret += SS + std::to_wstring(value % cmp_unit) + SS + L"minutes";
}
else if (value == cmp_unit){
ret = diff_str(hours::rep(1), dummy_to_pass);
}
else{
ret = std::to_wstring(value) + SS + L"minutes";
}
return ret;
}
std::wstring
diff_str(std::chrono::seconds::rep value, std::chrono::seconds dummy)
{
using namespace std::chrono;
std::wstring ret{ L"" };
auto cmp_unit = seconds(60).count();
auto dummy_to_pass = duration_cast<minutes>(dummy);
if (value > cmp_unit){
ret = diff_str(minutes::rep(value / cmp_unit), dummy_to_pass);
ret += SS + std::to_wstring(value % cmp_unit) + SS + L"seconds";
}
else if (value == cmp_unit){
ret = diff_str(minutes::rep(1), dummy_to_pass);
}
else{
ret = std::to_wstring(value) + SS + L"seconds";
}
return ret;
}
std::wstring
diff_str(std::chrono::milliseconds::rep value, std::chrono::milliseconds dummy)
{
using namespace std::chrono;
std::wstring ret{ L"" };
auto cmp_unit = milliseconds(1000).count();
auto dummy_to_pass = duration_cast<seconds>(dummy);
if (value > cmp_unit){
ret = diff_str(seconds::rep(value / cmp_unit), dummy_to_pass);
ret += SS + std::to_wstring(value % cmp_unit) + SS + L"milliseconds";
}else if (value == cmp_unit){
ret = diff_str(seconds::rep(1), dummy_to_pass);
}else{
ret = std::to_wstring(value) + SS + L"milliseconds";
}
return ret;
}
std::wstring
diff_str(std::chrono::microseconds::rep value, std::chrono::microseconds dummy)
{
using namespace std::chrono;
std::wstring ret{ L"" };
auto cmp_unit = microseconds(1000).count();
auto dummy_to_pass = duration_cast<milliseconds>(dummy);
if (value > cmp_unit){
ret = diff_str(milliseconds::rep(value / cmp_unit), dummy_to_pass);
ret += SS + std::to_wstring(value % cmp_unit) + SS + L"microseconds";
}
else if (value == cmp_unit){
ret = diff_str(milliseconds::rep(1), dummy_to_pass);
}
else{
ret = std::to_wstring(value) + SS + L"microseconds";
}
return ret;
}
};
///////////////////////////////////////////////////////////////////////////////
int main()
{
using namespace std::chrono;
using namespace std;
ExecutionTimer<high_resolution_clock, microseconds> exe_timer_micro;
ExecutionTimer<high_resolution_clock, milliseconds> exe_timer_milli;
exe_timer_micro.set_start();
exe_timer_milli.set_start();
for (size_t i = 0; i < (std::numeric_limits<unsigned int>::max()); i++)
{
if (0 == i % (32 * std::numeric_limits<unsigned short>::max())){
wcout << L".";
exe_timer_micro.set_end(high_resolution_clock::now());
exe_timer_milli.set_end(high_resolution_clock::now());
}
}
wcout << endl;
wcout << to_wstring(exe_timer_micro.diff()) << L" microseconds" << endl;
wcout << exe_timer_micro.diff_str() << endl;
wcout << to_wstring(exe_timer_milli.diff()) << L" milliseconds" << endl;
wcout << exe_timer_milli.diff_str() << endl;
}