- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要经常(每秒几次)生成字符串格式的 UTC 时间戳,而我的代码效率很低。有没有比我正在使用的方法更快的方法?可以假设该程序不会跨天运行。
void GenerateUTCTimestamp(std::string& out)
{
auto now = std::chrono::system_clock::now();
time_t tnow = std::chrono::system_clock::to_time_t(now);
tm* utc = gmtime(&tnow);
std::stringstream ss;
ss << std::setfill('0');
ss << std::setw(4) << utc->tm_year + 1900; // Year
ss << std::setw(2) << utc->tm_mon + 1; // Month
ss << std::setw(2) << utc->tm_mday; // Day
ss << '-';
ss << std::setw(2) << utc->tm_hour << ':'; // Hours
ss << std::setw(2) << utc->tm_min << ':'; // Minutes
ss << std::setw(2) << utc->tm_sec; // Seconds
out = ss.str();
}
最佳答案
你将很难找到比这更快的代码:
#include <chrono>
#include <string>
void
stamp(char* s, int i)
{
do
{
*s-- = char(i % 10) + '0';
i /= 10;
} while (i > 0);
}
void GenerateUTCTimestamp(std::string& out)
{
using namespace std;
using namespace std::chrono;
using days = duration<int, ratio<86400>>;
auto now = time_point_cast<seconds>(system_clock::now());
auto today = time_point_cast<days>(now);
auto s = now - today;
// y-m-d
auto z = today.time_since_epoch().count() + 719468;
const auto era = 5;
const auto doe = z - era * 146097;
const auto yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365;
const auto y = yoe + era * 400;
const auto doy = doe - (365*yoe + yoe/4 - yoe/100);
auto m = (5*doy + 2)/153;
const auto d = doy - (153*m+2)/5 + 1;
m = m + (m < 10 ? 3 : -9);
// h:M:s
const auto h = duration_cast<hours>(s);
s -= h;
const auto M = duration_cast<minutes>(s);
s -= M;
// format yyyymmdd-hh:MM:ss
out = "00000000-00:00:00";
stamp(&out[3], y);
stamp(&out[5], m);
stamp(&out[7], d);
stamp(&out[10], h.count());
stamp(&out[13], M.count());
stamp(&out[16], s.count());
}
此代码使用来自此处的公共(public)域算法 civil_from_days
:
http://howardhinnant.github.io/date_algorithms.html#civil_from_days
在哪里可以找到该算法的深入解释。
代码中的分支数被最小化,代码本身的大小也被最小化。
完全避免使用通用(和方便)流,而是选择不处理本地化、特征、宽字符、自定义宽度或对齐的基本整数到字符算法甚至负值。
除第一次调用外,通过重用和格式化直接进入out
完全避免了内存分配。
此代码确实有一个有限的有效范围:2000-03-01 到 2400-02-29。如果您需要使此代码在此范围之外的时间点有效,请将 era
的计算更改为:
const auto era = (z >= 0 ? z : z - 146096)/146097;
我将此代码放入 1000 次调用的循环中(使用相同的 string
),对其计时,然后对所有调用的时间进行平均。
在我的机器上(macOS、clang、libc++、-O3),原始代码大约需要 3.9µs,优化后的代码大约需要 150ns(大约快 25 倍)。
然后为了开心,我使用 Howard Hinnant's date library 实现了 GenerateUTCTimestamp
看看它在计时测试中的表现如何。它显然赢得了易用性测试(恕我直言):
#include "date.h"
void GenerateUTCTimestamp(std::string& out)
{
using namespace date;
using namespace std::chrono;
out = format("%Y%m%d-%T", time_point_cast<seconds>(system_clock::now()));
}
它的时钟频率为 2.5µs,比线程不安全的 C API 快 50%,但比优化代码慢很多。通用工具的灵 active 会降低性能。
日期库使用与优化工具相同的日历算法(除了使用通用的 era
),但像原始代码一样格式化为 stringstream
。当然,它还必须解析格式字符串。
关于c++ - 高效生成 UTC 时间戳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43963072/
给定一个带有多个 date_time 戳的字符串,我想 提取第一个戳及其前面的文本 候选字符串可以有一个或多个时间戳 后续的 date_time 戳记将被 sep="-" 隔开 后续date_time
是否可以合并从相机拍摄的文本和照片?我想在照片上标记日期和时间,但我在 Google 上找不到任何内容。 最佳答案 使用下面的代码来实现你所需要的。 Bitmap src = Bitm
有没有办法通过 Graph API 戳另一个用户?基于this post ,并使用 Graph Explorer ,我发布到“/USERID/pokes”,我已经授予它(Graph API 应用程序和
我有两个向左浮动的元素。一个是 body 的第一个 child ,另一个是容器的第一个 child ,容器是 body 的第二个 child 。 ...
我是一名优秀的程序员,十分优秀!