C++11中获取当前时间的最快方法是什么?

8

背景: 我正在编写一个高性能的C++11应用程序,其中一部分是删除不活动的连接。为此,我在连接对象中存储“最后活动”时间戳,在执行操作时更新。然后我有一个定时器,每隔几秒钟运行一次,循环遍历所有会话并删除不活动的连接。

目前我正在使用以下代码获取当前时间戳:

timestamp = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count()

我想知道是否有更快的方法来获取时间戳?我所说的更快是指获取时间戳本身的性能,而不是时间戳的分辨率。
对于我的特定应用程序来说,分辨率并不重要,可以低至一秒。此外,utc/local并不重要,我只是使用时间戳将其与通过相同方法获得的其他时间戳进行比较。
我希望保持跨平台性,但也欢迎具有条件编译的平台特定优化。

8
为什么不直接使用 timestamp = system_clock::now(); 呢? - nwp
6
你是否已经测量过时间戳获取是否成为瓶颈?你是否检查过(经过优化的!)生成的机器代码? - Some programmer dude
5
在64位系统中,本机字长为八个字节。即使在32位系统上复制八个字节也是微不足道的。这就是为什么测量检查生成的代码如此重要。像你这样的假设会导致过早优化,这是不好的。专注于编写良好、可读、可维护的代码。然后进行测量。接着找到瓶颈,只优化其中最差的部分,并加上大量的注释、文档和测试。 - Some programmer dude
4
如果性能真的是一个问题,而准确性不是,那么您可能根本不需要使用时间戳。相反,只需为每个连接保留一个计数器,在连接发生活动时将计数器重置为零。每当定时器启动时,让它为每个连接递增计数器,并断开任何计数器值上升超过(N)(对于您发现最有效的N值)的连接。 - Jeremy Friesner
2
在这种情况下,最好设计一个易于稍后更改的实现,并仅使用“足够好”的方法来推迟优化工作,直到您注意到问题为止。例如,定义一个类型别名或模板化您的代码以允许使用时钟的类型,并只使用其中一个标准时钟。稍后,您将能够更改所使用的时钟类型,包括具有兼容接口的用户定义类,该类可以封装您找到的任何替代解决方案。大多数情况下,您会发现您从未对其进行过优化,因为它从未成为问题。 - François Andrieux
显示剩余17条评论
2个回答

5
如果性能是一个真正的问题,而准确性不是,那么您可能根本不需要使用时间戳。相反,只需为每个连接保留一个计数器,每当连接发生活动时,将计数器重置为零。每当您的计时器触发时,让它为每个连接增加计数器,并断开任何计数器值上升超过(N)(对于您发现最有效的N值)的连接。

1
如果您不想让清理任务计时器精度成为问题,可以记录自上次运行以来的时间并将计数器递增相应的时间。这样,您就可以生成一个很好的近似解决方案,并且只在非性能关键线程上每隔几秒钟计算一次时间。 - Yakk - Adam Nevraumont

0

你可以为每个线程维护一个本地变量,并为每个线程添加一个timerfd(或者你可以使用select/epoll超时参数)来唤醒线程,每1毫秒一次。当select/epoll_wait返回时,调用now()获取时间戳,并将时间戳保存到线程本地变量中。

你也可以使用全局变量,例如std::atomic,并在select/epoll(在任何线程中)返回时更新它。如果你仍然认为这是瓶颈,可以使用单个线程和timerfd每1毫秒更新时间戳。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接