- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想在 C++ 中将包含日期时间字符串的巨大文件转换为自 UNIX 纪元(1970 年 1 月 1 日)以来的秒数。我需要非常快的计算,因为我需要处理大量的日期时间。
到目前为止,我已经尝试了两种选择。第一个是使用 mktime,定义于 time.h
.我尝试的第二个选项是 Howard Hinnant 的 date library带时区扩展。
这是我用来比较 mktime 和 Howard Hinnant 的 tz 之间性能的代码:
for( int i=0; i<RUNS; i++){
genrandomdate(&time_str);
time_t t = mktime(&time_str);
}
auto tz = current_zone()
for( int i=0; i<RUNS; i++){
genrandomdate(&time_str);
auto ymd = year{time_str.tm_year+1900}/(time_str.tm_mon+1)/time_str.tm_mday;
auto tcurr = make_zoned(tz, local_days{ymd} +
seconds{time_str.tm_hour*3600 + time_str.tm_min*60 + time_str.tm_sec}, choose::earliest);
auto tbase = make_zoned("UTC", local_days{January/1/1970});
auto dp = tcurr.get_sys_time() - tbase.get_sys_time() + 0s;
}
time for mktime : 0.000142s
time for tz : 0.018748s
最佳答案
您可以采取一些措施来优化 Howard Hinnant 的使用 date library :
auto tbase = make_zoned("UTC", local_days{January/1/1970});
// outside of loop:
auto utc_tz = locate_zone("UTC");
// inside of loop:
auto tbase = make_zoned(utc_tz, local_days{January/1/1970});
tbase
是循环无关的,所以整个事情都可以移到循环之外:
// outside of loop:
auto tbase = make_zoned("UTC", local_days{January/1/1970});
auto dp = tcurr.get_sys_time() - tbase.get_sys_time() + 0s;
auto dp = tcurr.get_sys_time().time_since_epoch();
tbase
的需要共。
tcurr.get_sys_time().time_since_epoch()
是自 1970-01-01 00:00:00 UTC 以来的持续时间,以秒为单位。秒的精度仅用于此示例,因为输入具有秒精度。
auto tcurr = make_zoned(tz, local_days{ymd} +
seconds{time_str.tm_hour*3600 + time_str.tm_min*60 + time_str.tm_sec}, choose::earliest);
auto tcurr = make_zoned(tz, local_days{ymd} + hours{time_str.tm_hour} +
minutes{time_str.tm_min} + seconds{time_str.tm_sec},
choose::earliest);
Is there a way to avoid this binary search if this time zone is also fixed. I mean can we get the time zone offset and DST offset and manually adjust the time point.
-DUSE_OS_TZDB=1
进行编译.这使用了具有更高性能的数据库的编译形式。
time_point
的值而改变。 ,你最终会重新发明
make_zoned
引擎盖下的逻辑。 .
auto tz = current_zone();
// Use a sample time_point to get the utc_offset:
auto info = tz->get_info(
local_days{year{time_str.tm_year+1900}/(time_str.tm_mon+1)/time_str.tm_mday}
+ hours{time_str.tm_hour} + minutes{time_str.tm_min}
+ seconds{time_str.tm_sec});
seconds utc_offset = info.first.offset;
for( int i=0; i<RUNS; i++){
genrandomdate(&time_str);
// Apply the offset manually:
auto ymd = year{time_str.tm_year+1900}/(time_str.tm_mon+1)/time_str.tm_mday;
auto tp = sys_days{ymd} + hours{time_str.tm_hour} +
minutes{time_str.tm_min} + seconds{time_str.tm_sec} - utc_offset;
auto dp = tp.time_since_epoch();
}
#include "date/tz.h"
#include <cassert>
#include <iostream>
#include <vector>
constexpr int RUNS = 1'000'000;
using namespace date;
using namespace std;
using namespace std::chrono;
vector<tm>
gendata()
{
vector<tm> v;
v.reserve(RUNS);
auto tz = current_zone();
auto tp = floor<seconds>(system_clock::now());
for (auto i = 0; i < RUNS; ++i, tp += 1s)
{
zoned_seconds zt{tz, tp};
auto lt = zt.get_local_time();
auto d = floor<days>(lt);
year_month_day ymd{d};
auto s = lt - d;
auto h = floor<hours>(s);
s -= h;
auto m = floor<minutes>(s);
s -= m;
tm x{};
x.tm_year = int{ymd.year()} - 1900;
x.tm_mon = unsigned{ymd.month()} - 1;
x.tm_mday = unsigned{ymd.day()};
x.tm_hour = h.count();
x.tm_min = m.count();
x.tm_sec = s.count();
x.tm_isdst = -1;
v.push_back(x);
}
return v;
}
int
main()
{
auto v = gendata();
vector<time_t> vr;
vr.reserve(v.size());
auto tz = current_zone(); // Using date
sys_seconds begin; // Using date, optimized
sys_seconds end; // Using date, optimized
seconds offset{}; // Using date, optimized
auto t0 = steady_clock::now();
for(auto const& time_str : v)
{
#if 0 // Using mktime
auto t = mktime(const_cast<tm*>(&time_str));
vr.push_back(t);
#elif 1 // Using date, easy
auto ymd = year{time_str.tm_year+1900}/(time_str.tm_mon+1)/time_str.tm_mday;
auto tp = local_days{ymd} + hours{time_str.tm_hour} +
minutes{time_str.tm_min} + seconds{time_str.tm_sec};
zoned_seconds zt{tz, tp};
vr.push_back(zt.get_sys_time().time_since_epoch().count());
#elif 0 // Using date, optimized
auto ymd = year{time_str.tm_year+1900}/(time_str.tm_mon+1)/time_str.tm_mday;
auto tp = local_days{ymd} + hours{time_str.tm_hour} +
minutes{time_str.tm_min} + seconds{time_str.tm_sec};
sys_seconds zt{(tp - offset).time_since_epoch()};
if (!(begin <= zt && zt < end))
{
auto info = tz->get_info(tp);
offset = info.first.offset;
begin = info.first.begin;
end = info.first.end;
zt = sys_seconds{(tp - offset).time_since_epoch()};
}
vr.push_back(zt.time_since_epoch().count());
#endif
}
auto t1 = steady_clock::now();
cout << (t1-t0)/v.size() << " per conversion\n";
auto i = vr.begin();
for(auto const& time_str : v)
{
auto t = mktime(const_cast<tm*>(&time_str));
assert(t == *i);
++i;
}
}
mktime
.
3849ns per conversion
tz.h
以最简单的方式使用
USE_OS_TZDB=0
3976ns per conversion
mktime
稍慢解决方案。
tz.h
以最简单的方式使用
USE_OS_TZDB=1
55ns per conversion
tz.h
以优化的方式,利用时间分组时间戳的先验知识。如果假设为假,则性能会受到影响,但正确性不会受到影响。
15ns per conversion
USE_OS_TZDB
环境。但性能取决于输入数据不会经常更改 UTC 偏移量的事实。对于不明确或不存在的本地时间点,此解决方案也很粗心。这样的本地时间点没有唯一的 UTC 映射。如果遇到这样的本地时间点,解决方案 2 和 3 将抛出异常。
-lpthread
)。
==20645== Process terminating with default action of signal 6 (SIGABRT)
==20645== at 0x5413428: raise (raise.c:54)
==20645== by 0x5415029: abort (abort.c:89)
==20645== by 0x4EC68F6: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==20645== by 0x4ECCA45: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==20645== by 0x4ECCA80: std::terminate() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==20645== by 0x4ECCCB3: __cxa_throw (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==20645== by 0x4EC89B8: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==20645== by 0x406AF9: void std::call_once<date::time_zone::init() const::{lambda()#1}>(std::once_flag&, date::time_zone::init() const::{lambda()#1}&&) (mutex:698)
==20645== by 0x40486C: date::time_zone::init() const (tz.cpp:2114)
==20645== by 0x404C70: date::time_zone::get_info_impl(std::chrono::time_point<date::local_t, std::chrono::duration<long, std::ratio<1l, 1l> > >) const (tz.cpp:2149)
==20645== by 0x418E5C: date::local_info date::time_zone::get_info<std::chrono::duration<long, std::ratio<1l, 1l> > >(std::chrono::time_point<date::local_t, std::chrono::duration<long, std::ratio<1l, 1l> > >) const (tz.h:904)
==20645== by 0x418CB2: std::chrono::time_point<std::chrono::_V2::system_clock, std::common_type<std::chrono::duration<long, std::ratio<1l, 1l> >, std::chrono::duration<long, std::ratio<1l, 1l> > >::type> date::time_zone::to_sys_impl<std::chrono::duration<long, std::ratio<1l, 1l> > >(std::chrono::time_point<date::local_t, std::chrono::duration<long, std::ratio<1l, 1l> > >, date::choose, std::integral_constant<bool, false>) const (tz.h:947)
==20645==
关于c++ - 在 C++ 中将带有时区的日期时间字符串转换为 UNIX 时间戳的快速方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56191222/
如何使用 SPListCollection.Add(String, String, String, String, Int32, String, SPListTemplate.QuickLaunchO
我刚刚开始使用 C++ 并且对 C# 有一些经验,所以我有一些一般的编程经验。然而,似乎我马上就被击落了。我试过在谷歌上寻找,以免浪费任何人的时间,但没有结果。 int main(int argc,
这个问题已经有答案了: In Java 8 how do I transform a Map to another Map using a lambda? (8 个回答) Convert a Map>
我正在使用 node + typescript 和集成的 swagger 进行 API 调用。我 Swagger 提出以下要求 http://localhost:3033/employees/sear
我是 C++ 容器模板的新手。我收集了一些记录。每条记录都有一个唯一的名称,以及一个字段/值对列表。将按名称访问记录。字段/值对的顺序很重要。因此我设计如下: typedef string
我需要这两种方法,但j2me没有,我找到了一个replaceall();但这是 replaceall(string,string,string); 第二个方法是SringBuffer但在j2me中它没
If string is an alias of String in the .net framework为什么会发生这种情况,我应该如何解释它: type JustAString = string
我有两个列表(或字符串):一个大,另一个小。 我想检查较大的(A)是否包含小的(B)。 我的期望如下: 案例 1. B 是 A 的子集 A = [1,2,3] B = [1,2] contains(A
我有一个似乎无法解决的小问题。 这里...我有一个像这样创建的输入... var input = $(''); 如果我这样做......一切都很好 $(this).append(input); 如果我
我有以下代码片段 string[] lines = objects.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.No
这可能真的很简单,但我已经坚持了一段时间了。 我正在尝试输出一个字符串,然后输出一个带有两位小数的 double ,后跟另一个字符串,这是我的代码。 System.out.printf("成本:%.2
以下是 Cloud Firestore 列表查询中的示例之一 citiesRef.where("state", ">=", "CA").where("state", "= 字符串,我们在Stack O
我正在尝试检查一个字符串是否包含在另一个字符串中。后面的代码非常简单。我怎样才能在 jquery 中做到这一点? function deleteRow(locName, locID) { if
这个问题在这里已经有了答案: How to implement big int in C++ (14 个答案) 关闭 9 年前。 我有 2 个字符串,都只包含数字。这些数字大于 uint64_t 的
我有一个带有自定义转换器的 Dozer 映射: com.xyz.Customer com.xyz.CustomerDAO customerName
这个问题在这里已经有了答案: How do I compare strings in Java? (23 个回答) 关闭 6 年前。 我想了解字符串池的工作原理以及一个字符串等于另一个字符串的规则是
我已阅读 this问题和其他一些问题。但它们与我的问题有些无关 对于 UILabel 如果你不指定 ? 或 ! 你会得到这样的错误: @IBOutlet property has non-option
这两种方法中哪一种在理论上更快,为什么? (指向字符串的指针必须是常量。) destination[count] 和 *destination++ 之间的确切区别是什么? destination[co
This question already has answers here: Closed 11 years ago. Possible Duplicates: Is String.Format a
我有一个Stream一个文件的,现在我想将相同的单词组合成 Map这很重要,这个词在 Stream 中出现的频率. 我知道我必须使用 collect(Collectors.groupingBy(..)
我是一名优秀的程序员,十分优秀!