我正在尝试为C ++程序创建一个日志文件。我的目标是在程序的两点放置两个时间戳,并在文件中打印这两点之间的CPU时间周期。我这样做是因为我想知道代码的哪些部分最耗时,因此可以进行改进(因此可能要测量几块代码)。到目前为止,我已经制作了一个函数,该函数在被调用时将作为参数传递的字符串打印到文件中:
#define LOGFILE "myprog.log"
void Log (std::string message){
std::ofstream ofs;
ofs.open(LOGFILE, std::ofstream::out | std::ios::app);
ofs << message << std::endl;
ofs.close();
}
但是,我很难弄清楚如何打印CPU时间戳。首先,我不知道应该使用哪种时间测量格式(我应该使用chrono还是time_t类型?)我正在尝试打印时间段,因此如果存在持续时间类型,这会有所帮助(我我尝试了chrono :: duration,但似乎需要C ++ 11支持)。其次,鉴于我知道要使用哪种类型,如何将其打印到文件中?有没有一种方法可以将该类型转换为字符串?还是可以将其直接传递给函数并以某种方式打印?
最近几天这让我很烦恼,而且我似乎无法弄清楚,因此任何输入都会非常有帮助。预先感谢!
答案 0 :(得分:4)
您将要使用std::chrono::system_clock
来获取此时间戳。 请勿使用std::chrono::steady_clock
或std::chrono::high_resolution_clock
,因为它们是用于进行高精度计时测量的,因此不保证保真度或对壁钟时间的准确性。
auto now = std::chrono::system_clock::now();
//now is a time_point object describing the instant it was recorded according to your system clock
在C ++ 20中,这很简单。
std::string formatted_time = std::chrono::format("%F_%T", now);
ofs << formatted_time << ": " << message << std::endl;
%F
替代%Y-%m-%D
,后者将以ISO格式(即2018-10-09
)输出年月日。%T
与%H:%M:%S
相同,它将输出一个时间,即17:55:34.786
有关更多选项/详情,请参见std::chrono::format
的规范。
考虑Howard Hinnant's date
library,其中大多数已作为chrono
库的新部分并入C ++ 20。该库中的format
函数使用与上述C ++ 20版本相同的语法。
答案 1 :(得分:1)
我通常将自己的实现用于此类事情。
#include <chrono>
#include <ctime>
// strftime format
#define LOGGER_PRETTY_TIME_FORMAT "%Y-%m-%d %H:%M:%S"
// printf format
#define LOGGER_PRETTY_MS_FORMAT ".%03d"
// convert current time to milliseconds since unix epoch
template <typename T>
static int to_ms(const std::chrono::time_point<T>& tp)
{
using namespace std::chrono;
auto dur = tp.time_since_epoch();
return static_cast<int>(duration_cast<milliseconds>(dur).count());
}
// format it in two parts: main part with date and time and part with milliseconds
static std::string pretty_time()
{
auto tp = std::chrono::system_clock::now();
std::time_t current_time = std::chrono::system_clock::to_time_t(tp);
// this function use static global pointer. so it is not thread safe solution
std::tm* time_info = std::localtime(¤t_time);
char buffer[128];
int string_size = strftime(
buffer, sizeof(buffer),
LOGGER_PRETTY_TIME_FORMAT,
time_info
);
int ms = to_ms(tp) % 1000;
string_size += std::snprintf(
buffer + string_size, sizeof(buffer) - string_size,
LOGGER_PRETTY_MS_FORMAT, ms
);
return std::string(buffer, buffer + string_size);
}
它以2018-09-23 21:58:52.642
格式返回当前时间。
是的,它要求--std=c++11
或更高。
答案 2 :(得分:1)
作记录:
如果像我一样C ++ 20功能不可用,则可以使用以下功能:
#include <ctime>
#include <iomanip>
#include <iostream>
using namespace std ;
time_t now = time(nullptr) ;
cout << put_time(localtime(&now), "%T") << endl ;
put_time在iomanip库中定义,请查看https://en.cppreference.com/w/cpp/io/manip/put_time,并且time_t和localtime来自ctime https://en.cppreference.com/w/cpp/chrono/c/ctime
答案 3 :(得分:0)
如果您想要更手动的方法,这就是我以前使用的
char buffer[MAX_BUFFER_SIZE];
time_t t = time(NULL);
struct tm *lt = localtime(&t);
snprintf(buffer, MAX_BUFFER_SIZE, "%02d/%02d/%02d %02d:%02d:%02d", lt->tm_mon+1, lt->tm_mday, lt->tm_year%100, lt->tm_hour, lt->tm_min, lt->tm_sec);
然后仅将 buffer 输出到文件中,该缓冲区现在包含时间的字符串表示形式。