你會遇到麻煩比這更快的查找代碼:
#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
您是否測量了您的功能所需的時間?它真的「太慢」了嗎?我希望你的執行速度對於一秒稱爲「幾次」的功能來說並不明顯。 –