Skip to content

Commit fa1448d

Browse files
Use lower_bound instead of find_if to lookup time_zones. (#5548)
Co-authored-by: Stephan T. Lavavej <[email protected]>
1 parent 9ef878d commit fa1448d

File tree

4 files changed

+38
-2
lines changed

4 files changed

+38
-2
lines changed

benchmarks/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ add_benchmark(has_single_bit src/has_single_bit.cpp)
114114
add_benchmark(iota src/iota.cpp)
115115
add_benchmark(is_sorted_until src/is_sorted_until.cpp)
116116
add_benchmark(locale_classic src/locale_classic.cpp)
117+
add_benchmark(locate_zone src/locate_zone.cpp)
117118
add_benchmark(minmax_element src/minmax_element.cpp)
118119
add_benchmark(mismatch src/mismatch.cpp)
119120
add_benchmark(move_only_function src/move_only_function.cpp)

benchmarks/src/locate_zone.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
#include "benchmark/benchmark.h"
5+
#include <chrono>
6+
7+
void locate_zone(benchmark::State& state) {
8+
const auto& db = std::chrono::get_tzdb();
9+
for (auto _ : state) {
10+
for (const auto& z : db.zones) {
11+
auto res = db.locate_zone(z.name());
12+
benchmark::DoNotOptimize(res);
13+
}
14+
}
15+
}
16+
17+
BENCHMARK(locate_zone);
18+
19+
BENCHMARK_MAIN();

stl/inc/chrono

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2105,8 +2105,14 @@ namespace chrono {
21052105

21062106
template <class _Ty>
21072107
_NODISCARD const _Ty* _Locate_zone_impl(const vector<_Ty>& _Vec, string_view _Name) {
2108-
const auto _Result = _STD find_if(_Vec.begin(), _Vec.end(), [&](auto& _Tz) { return _Tz.name() == _Name; });
2109-
return _Result == _Vec.end() ? nullptr : &*_Result;
2108+
// N5008 [time.zone.db.tzdb]/1: "Each vector in a tzdb object is sorted to enable fast lookup."
2109+
const auto _Result = _STD lower_bound(
2110+
_Vec.begin(), _Vec.end(), _Name, [](const auto& _Tz, const auto& _Sv) { return _Tz.name() < _Sv; });
2111+
if (_Result != _Vec.end() && _Result->name() == _Name) {
2112+
return &*_Result;
2113+
} else {
2114+
return nullptr;
2115+
}
21102116
}
21112117

21122118
_EXPORT_STD struct tzdb {

tests/std/tests/P0355R7_calendars_and_time_zones_time_zones/test.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,15 @@ void timezone_precision_test() {
393393
}
394394
}
395395

396+
void timezone_sorted_vectors_test() {
397+
// N5008 [time.zone.db.tzdb]/1: "Each vector in a tzdb object is sorted to enable fast lookup."
398+
const auto& my_tzdb = get_tzdb();
399+
400+
assert(ranges::is_sorted(my_tzdb.zones));
401+
assert(ranges::is_sorted(my_tzdb.links));
402+
assert(ranges::is_sorted(my_tzdb.leap_seconds));
403+
}
404+
396405
void test() {
397406
timezone_tzdb_list_test();
398407
timezone_version_test();
@@ -401,6 +410,7 @@ void test() {
401410
timezone_to_local_test();
402411
timezone_local_info_test();
403412
timezone_precision_test();
413+
timezone_sorted_vectors_test();
404414
}
405415

406416
int main() {

0 commit comments

Comments
 (0)