我在C++中使用time.h来测量函数的时间.
clock_t t = clock();
someFunction();
printf("\nTime taken: %.4fs\n", (float)(clock() - t)/CLOCKS_PER_SEC);
Run Code Online (Sandbox Code Playgroud)
但是,我总是把时间花在0.0000上.clock()和t单独打印时,具有相同的值.我想知道是否有办法在C++中精确测量时间(可能是纳秒级).我正在使用VS2010.
在C++ 11中,你仍然需要使用std::localtime和std::gmtime作为间接来打印std::chrono::time_point.这些函数在C++ 11引入的多线程环境中使用是不安全的,因为它们返回一个指向内部静态结构的指针.这尤其令人讨厌,因为C++ 11引入了方便的功能std::put_time,由于同样的原因几乎无法使用.
为什么这么根本被打破或者我忽略了什么?
如何从对象中提取年,月,日,小时,分钟,秒和毫秒std::chrono::time_point?
我只看到了如何从a中提取例如秒的总量的示例duration.
我想要的只是以毫秒为单位获取纪元以来的时间并将其存储在无符号长整数中.
我发现了这个相关的问题.但老实说,这不是执行这么简单任务的最简单方法,是吗?我希望更简单的东西,但在std :: chrono引用中找不到任何东西.任何建议都是最受欢迎的.我不一定要使用std::chrono,但我希望它与平台无关.
我有一个愚蠢的问题.我尝试切换到c ++ 11标头,其中一个是chrono.但我的问题是我无法控制时间操作的结果.例如:
auto t=std::chrono::high_resolution_clock::now();
cout<<t.time_since_epoch();
Run Code Online (Sandbox Code Playgroud)
得到:
初始化
‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char, _Traits = std::char_traits<char>, _Tp = std::chrono::duration<long int, std::ratio<1l, 1000000l> >]’... /usr/include/c++/4.6/ostream的 参数1
cout<<(uint64_t)t.time_since_epoch();
Run Code Online (Sandbox Code Playgroud)
给出无效的演员
让我通过这个测试程序问我的问题:
#include <iostream>
#include <chrono>
using std::chrono::nanoseconds;
using std::chrono::duration_cast;
int main(int argc, char* argv[])
{
std::cout << "resolution (nano) = " << (double) std::chrono::high_resolution_clock::period::num
/ std::chrono::high_resolution_clock::period::den * 1000 * 1000 * 1000 << std::endl;
auto t1 = std::chrono::high_resolution_clock::now();
std::cout << "how much nanoseconds std::cout takes?" << std::endl;
auto t2 = std::chrono::high_resolution_clock::now();
auto diff = t2-t1;
nanoseconds ns = duration_cast<nanoseconds>(diff);
std::cout << "std::cout takes " << ns.count() << " nanoseconds" << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我机器上的输出:
分辨率(纳米)= 100
std :: cout需要多少纳秒? …
std::chrono::duration自固定日期起如何获得?我需要这个来转换std::chrono::time_point为unix时间戳.
将代码插入XXX
auto unix_epoch_start = XXX;
auto time = std::chrono::system_clock::now();
auto delta = time - unix_epoc_start;
auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(delta).count();
Run Code Online (Sandbox Code Playgroud)
我知道time_point有一种方法,time_since_epoch()但不能保证这与unix时代(1970年1月1日00:00:00 UTC)相同.
某些C++实现(例如,电池供电的嵌入式设备)可能没有用或无法跟踪当前的日期和时间.
的C标准具体地允许这样的实施方式.引用ISO/IEC 9899:1999 7.23.2.4(强调我的):
time函数返回实现对当前日历时间的最佳近似值.如果日历时间不可用,则返回值(time_t)( - 1).
C++ 11引入了chrono库和std::chrono::system_clock::now()函数,用于从系统范围的实时时钟获取挂钟时间.该函数被声明为noexcept,因此它不能抛出任何异常来指示不可用,也不允许返回任何特殊值(如-1C的情况).
但是对于C++ 11,C++ 14和C++ 17,仍然存在漏洞.标准没有指定时钟的纪元,因此符合要求的实施可以将纪元设置为启动时(或程序启动)并仍满足标准要求的时间点.
目前的C++ 20草案将填补这个漏洞并需要system_clock使用Unix时间.换句话说,不知道当前时间的C++实现是不符合的.
这是标准委员会的疏忽吗?符合标准的C++实现如何表明它不知道当前的日期和时间?
(请注意,在标准的其它部分这一问题得到解决.例如,一个实现可以设置__TIME__和__DATE__宏来实现自定义的值,如果实际时间和日期不详).
我正在阅读这个优秀的答案,它使用滑稽的持续时间单位microfortnights以一种难忘的方式说明一个好点.
typedef std::ratio<756, 625> microfortnights;
std::chrono::duration<int, microfortnights> two_weeks(1000000);
Run Code Online (Sandbox Code Playgroud)
问题出现在我身上:
如果我真的想这样做(更可能是其他一些非平凡的持续时间,例如帧中可用的时间,或处理器的N个周期),最好的方法是什么?
我知道,ratio<N, D>将创建的每个值相关联的独特型N和D.所以它ratio<4, 6>是一种不同的类型ratio<2, 3>,即使它们代表相同(减少)的分数.我是否总是需要进行数学计算以简化转换因子以减少术语?
写起来会更方便:
using microfortnights = std::chrono::duration<long, ratio<86400*14, 1000000>>;
Run Code Online (Sandbox Code Playgroud)
代替:
using microfortnights = std::chrono::duration<long, ratio<756, 625>>;
Run Code Online (Sandbox Code Playgroud)
但那么这些将是两种不同的类型,而不是相同的类型.第一个表达式更容易检查是否正确.但是这个部分有许多表示,第二部分可以说是规范的,因此是首选的.如果我有太多类型在我的程序周围徘徊,实际上代表相同的单位,那么这可能会导致不必要的模板代码膨胀.
制作和使用std::chrono::duration<double>无穷大作为包含值是否合法?
std::chrono::duration<double>{ std::numeric_limits<double>::infinity() };
Run Code Online (Sandbox Code Playgroud)
它会表现得像我期望的那样,在添加或减去其他持续时间时保持无限的价值吗?
我通过cppreference挖了但是我发现讨论这个问题的唯一一件事就是duration_cast注意到这一点的页面:
当浮点值为NaN,无穷大或太大而无法通过目标的整数类型表示时,从浮点持续时间转换为整数持续时间会受到未定义的行为.否则,转换为整数持续时间会受到截断,就像使用static_cast到整数类型一样.
这似乎暗示它是合法的,但只是以一种反面的方式.
(我使用的类型代表"请在X秒内唤醒我"的方式,正无限是一个有用的哨兵,代表"当我醒来时我真的不在乎")