БлогNot. C++: ещё один таймер с периодом

C++: ещё один таймер с периодом

Небольшой класс решает задачу "сопровождения" некоторого вычислительного процесса периодически выводимым в консоль сообщением.

Ниже в листинге показан класс, который может через заданный в секундах интервал времени выводить в консоль что-то, показывающее, что процесс идёт.

У нас он выводит текущее количество тиков в секунду, которое вычислил, но можно и просто какую-нибудь точечку печатать (показано комментарием в функции Tick).

В этом же листинге - пример применения класса TimeRanger.

Проверено в Visual Studio 2015.

//Visual Studio 2015
#include <iostream>
#include <ctime>
using namespace std;

class TimeRanger { 
protected:
 time_t timePoint;
 time_t timePeriod;
 size_t tickCount;
public:
 TimeRanger(time_t period);
 void Tick();
};

TimeRanger::TimeRanger (time_t period) : timePoint(time(NULL)), timePeriod(period), tickCount(0) { }

void TimeRanger::Tick() {
 tickCount++;
 time_t now = time(NULL);
 if ((now - timePoint) >= timePeriod) {
  //выведет инфу о текущем TPS (тиках в секунду)
  size_t tps = 0.0;
  if (tickCount > 0) tps = tickCount / (now - timePoint);
  cout << "TPS: " << tps << " ";
  //cout << "."; //или можно вот так вместо строчки выше
  tickCount = 0;
  timePoint = now;
 }
}

void somethingCode() { //Демо, здесь может быть Ваш код
 volatile size_t anchor = 0; //Чтобы не оптимизировал переменную - volatile
 for (size_t x = 0; x < 0xffff; ++x) { //Просто гоняем цикл
  anchor = x;
 }
}

int main() {
 time_t start = time(NULL);

 TimeRanger myWatch (3); //Создаем таймер с интервалом в 3 секунды
 for (time_t latest = start; (latest - start) <= 15; latest = time(NULL)) {
  //Пока не пройдёт 15 секунд
  somethingCode(); //Делаем что-то
  myWatch.Tick(); //И с заданным периодом выводим тикалку
 }
 cout << "OK, press Enter";
 cin.get();
 return 0;
}

Вот альтернативный класс таймера и пример его использования.

Файл Timer.h
#pragma once
#include <ctime>
#include <chrono>
#include <string>
#include <sstream>
#include <iomanip>
#include <cmath>

class Timer {
	std::chrono::high_resolution_clock::time_point start;
public:
	Timer();
	double stop();
	std::string get();
};
Файл Timer.cpp
#include "Timer.h"

Timer::Timer() {
	this->start = std::chrono::high_resolution_clock::now();
}
double Timer::stop() {
	std::chrono::high_resolution_clock::time_point end =
		std::chrono::high_resolution_clock::now();
	std::chrono::duration <double> time_span = std::chrono::duration_cast
		<std::chrono::duration<double>>(end - start);
	return time_span.count();
}
std::string Timer::get() {
	double end = this->stop();
	size_t h = end / 3600;
	end -= h * 3600;
	size_t m = end / 60;
	end -= m * 60;
	size_t s = std::round(end);
	std::stringstream ss;
	ss << std::setw(2) << std::setfill('0') << h << ':' <<
		std::setw(2) << std::setfill('0') << m << ':' << 
		std::setw(2) << std::setfill('0') << s;
	return ss.str();
}
Пример использования
#include <iostream>
#include <thread>
#include "Timer.h"

int main() {
 Timer t; //создали и запустили
 for (size_t i = 0; i < 10; i++) { //10 раз вывели время
  std::cout << t.get() << std::endl;
  std::this_thread::sleep_for(std::chrono::seconds(1));
 }
 double time = t.stop(); //сохранили время в переменной
 std::cout << time << std::endl;
 //отсчёт не останавливается
 return 0;
}

Для возврата текущего времени класс можно дополнить таким методом:

std::string Timer::getCurrentTime() {
    std::stringstream ss;
    std::chrono::system_clock::time_point today = std::chrono::system_clock::now();
    time_t mytime = std::chrono::system_clock::to_time_t(today);
    ss << std::put_time(localtime(&mytime), "%T");
    return ss.str();
}

12.05.2018, 14:29 [2320 просмотров]


теги: c++ алгоритм время

К этой статье пока нет комментариев, Ваш будет первым