Skip to content

Instantly share code, notes, and snippets.

@a-voel
Created April 26, 2021 20:03
Show Gist options
  • Save a-voel/9b0347397db95bc829953079ad047e74 to your computer and use it in GitHub Desktop.
Save a-voel/9b0347397db95bc829953079ad047e74 to your computer and use it in GitHub Desktop.
#include "progressreporter.h"
#include <iostream>
#include <cmath>
#include <sstream>
#include <iomanip>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
double GetTime(){
LARGE_INTEGER counter;
LARGE_INTEGER freq;
QueryPerformanceCounter(&counter);
QueryPerformanceFrequency(&freq);
return 1.0*counter.QuadPart / freq.QuadPart;
}
#else
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
double GetTime(){
struct timespec time;
clock_gettime(CLOCK_MONOTONIC, &time);
return (double)time.tv_sec+time.tv_nsec*1.0e9;
}
#endif
ProgressReporter::ProgressReporter(std::string ident, int N)
:N(N), speed(0.0f), ident(ident), clear(false)
{
last_report_step = 0;
last_report_time = GetTime();
start_time = GetTime();
}
static std::string FormatTime(double time){
int sec = (int)std::round(::fmod(time, 60));
int min = (int)std::trunc(time/60);
std::stringstream ss;
//ss << std::fixed << std::setprecision(2);
ss << min << ":";
ss << std::setw(2) << std::setfill('0') << sec;
return ss.str();
}
void ProgressReporter::setClear(bool c){
clear = c;
}
void ProgressReporter::didStep(int step)
{
auto time = GetTime();
auto diff = time - last_report_time;
if (diff > 5.0 || (step-last_report_step)> 5*N/100) {
auto elapsed_time = time - start_time;
auto factor = 1.0*step / N;
auto newspeed = 1.0*diff/ (step - last_report_step);
if (speed == 0.0){
speed = newspeed;
}
else {
speed = 0.5*speed + 0.5*newspeed;
}
if (clear)
for(int i = 0; i != 16; i++){
std::cerr << "\b\b\b\b\b\b\b\b\b\b";
}
std::cerr << std::setprecision(1) << std::fixed;
std::cerr <<ident <<" ";
std::cerr << std::setw(5) << std::setfill(' ') << factor * 100;
std::cerr << "% done in " << FormatTime(elapsed_time) << ". Expected remaining time: "
<< FormatTime(newspeed *(N-step));
if (!clear){
std::cerr << std::endl;
}else{
std::cerr << " ";
}
last_report_time = time;
last_report_step = step;
}
}
#pragma once
#include <string>
class ProgressReporter {
public:
ProgressReporter(std::string ident, int numberSteps);
void setClear(bool c);
void didStep(int step);
private:
bool clear;
int N;
std::string ident;
double speed;
double start_time;
int last_report_step;
double last_report_time;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment