你会遇到麻烦比这更快的查找代码:
#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());
}
该代码使用公共域算法civil_from_days
从这里:
http://howardhinnant.github.io/date_algorithms.html#civil_from_days
您可以在其中找到该算法的深入解释米
代码中的分支数量被最小化,并且代码大小本身被最小化。
完全避免使用通用(方便)流,而是选择一种不涉及本地化,特征,宽字符,自定义宽度或对齐的纯粹整数到字符算法,或者甚至是负值。
除了第一次调用,内存分配完全避免通过重用和格式化直接out
。
此代码确实具有有限有效范围:2000-03-01到2400年2月29日。如果您需要使该代码有效的个时刻超出此范围,改变era
来计算:
const auto era = (z >= 0 ? z : z - 146096)/146097;
我把这个代码在1000调用一个循环(使用相同的string
),对它进行计时,并在所有呼叫上平均时间。
在我的机器上(macOS,clang,libC++,-O3),原始代码大约需要3.9 µ s,优化后的代码大约需要150ns(约快25倍)。
然后对于微笑,我实施GenerateUTCTimestamp
使用Howard Hinnant's date library看看它是如何在时间测试中表现。它清楚地赢得易用性试验(IMHO)的:
#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 µ秒,比螺纹不安全C API快50%,但大量比优化代码更慢。对于通用工具的灵活性,性能会受到影响。
日期库使用与优化工具相同的日历算法(使用广义era
除外),但格式化为像原始代码一样的stringstream
。它当然也必须解析格式化字符串。
请不要张贴链接到代码,邮编本身。 – dasblinkenlight
每秒运行几次的“低效率”代码必须非常低效才能产生显着的差异。您是否分析了此代码片段的“低效率”是否会将性能降至不可接受的级别? – dasblinkenlight
您是否测量了您的功能所需的时间?它真的“太慢”了吗?我希望你的执行速度对于一秒称为“几次”的功能来说并不明显。 –