1 // Copyright 2016 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <algorithm>
16 #include <cassert>
17 #include <chrono>
18 #include <ctime>
19 #include <random>
20 #include <string>
21 #include <vector>
22
23 #include "benchmark/benchmark.h"
24 #include "absl/time/internal/cctz/include/cctz/civil_time.h"
25 #include "absl/time/internal/cctz/include/cctz/time_zone.h"
26 #include "time_zone_impl.h"
27
28 namespace {
29
30 namespace cctz = absl::time_internal::cctz;
31
BM_Difference_Days(benchmark::State & state)32 void BM_Difference_Days(benchmark::State& state) {
33 const cctz::civil_day c(2014, 8, 22);
34 const cctz::civil_day epoch(1970, 1, 1);
35 while (state.KeepRunning()) {
36 benchmark::DoNotOptimize(c - epoch);
37 }
38 }
39 BENCHMARK(BM_Difference_Days);
40
BM_Step_Days(benchmark::State & state)41 void BM_Step_Days(benchmark::State& state) {
42 const cctz::civil_day kStart(2014, 8, 22);
43 cctz::civil_day c = kStart;
44 while (state.KeepRunning()) {
45 benchmark::DoNotOptimize(++c);
46 }
47 }
48 BENCHMARK(BM_Step_Days);
49
BM_GetWeekday(benchmark::State & state)50 void BM_GetWeekday(benchmark::State& state) {
51 const cctz::civil_day c(2014, 8, 22);
52 while (state.KeepRunning()) {
53 benchmark::DoNotOptimize(cctz::get_weekday(c));
54 }
55 }
56 BENCHMARK(BM_GetWeekday);
57
BM_NextWeekday(benchmark::State & state)58 void BM_NextWeekday(benchmark::State& state) {
59 const cctz::civil_day kStart(2014, 8, 22);
60 const cctz::civil_day kDays[7] = {
61 kStart + 0, kStart + 1, kStart + 2, kStart + 3,
62 kStart + 4, kStart + 5, kStart + 6,
63 };
64 const cctz::weekday kWeekdays[7] = {
65 cctz::weekday::monday, cctz::weekday::tuesday, cctz::weekday::wednesday,
66 cctz::weekday::thursday, cctz::weekday::friday, cctz::weekday::saturday,
67 cctz::weekday::sunday,
68 };
69 while (state.KeepRunningBatch(7 * 7)) {
70 for (const auto from : kDays) {
71 for (const auto to : kWeekdays) {
72 benchmark::DoNotOptimize(cctz::next_weekday(from, to));
73 }
74 }
75 }
76 }
77 BENCHMARK(BM_NextWeekday);
78
BM_PrevWeekday(benchmark::State & state)79 void BM_PrevWeekday(benchmark::State& state) {
80 const cctz::civil_day kStart(2014, 8, 22);
81 const cctz::civil_day kDays[7] = {
82 kStart + 0, kStart + 1, kStart + 2, kStart + 3,
83 kStart + 4, kStart + 5, kStart + 6,
84 };
85 const cctz::weekday kWeekdays[7] = {
86 cctz::weekday::monday, cctz::weekday::tuesday, cctz::weekday::wednesday,
87 cctz::weekday::thursday, cctz::weekday::friday, cctz::weekday::saturday,
88 cctz::weekday::sunday,
89 };
90 while (state.KeepRunningBatch(7 * 7)) {
91 for (const auto from : kDays) {
92 for (const auto to : kWeekdays) {
93 benchmark::DoNotOptimize(cctz::prev_weekday(from, to));
94 }
95 }
96 }
97 }
98 BENCHMARK(BM_PrevWeekday);
99
100 const char RFC3339_full[] = "%Y-%m-%d%ET%H:%M:%E*S%Ez";
101 const char RFC3339_sec[] = "%Y-%m-%d%ET%H:%M:%S%Ez";
102
103 const char RFC1123_full[] = "%a, %d %b %Y %H:%M:%S %z";
104 const char RFC1123_no_wday[] = "%d %b %Y %H:%M:%S %z";
105
106 // A list of known time-zone names.
107 // TODO: Refactor with src/time_zone_lookup_test.cc.
108 const char* const kTimeZoneNames[] = {"Africa/Abidjan",
109 "Africa/Accra",
110 "Africa/Addis_Ababa",
111 "Africa/Algiers",
112 "Africa/Asmara",
113 "Africa/Asmera",
114 "Africa/Bamako",
115 "Africa/Bangui",
116 "Africa/Banjul",
117 "Africa/Bissau",
118 "Africa/Blantyre",
119 "Africa/Brazzaville",
120 "Africa/Bujumbura",
121 "Africa/Cairo",
122 "Africa/Casablanca",
123 "Africa/Ceuta",
124 "Africa/Conakry",
125 "Africa/Dakar",
126 "Africa/Dar_es_Salaam",
127 "Africa/Djibouti",
128 "Africa/Douala",
129 "Africa/El_Aaiun",
130 "Africa/Freetown",
131 "Africa/Gaborone",
132 "Africa/Harare",
133 "Africa/Johannesburg",
134 "Africa/Juba",
135 "Africa/Kampala",
136 "Africa/Khartoum",
137 "Africa/Kigali",
138 "Africa/Kinshasa",
139 "Africa/Lagos",
140 "Africa/Libreville",
141 "Africa/Lome",
142 "Africa/Luanda",
143 "Africa/Lubumbashi",
144 "Africa/Lusaka",
145 "Africa/Malabo",
146 "Africa/Maputo",
147 "Africa/Maseru",
148 "Africa/Mbabane",
149 "Africa/Mogadishu",
150 "Africa/Monrovia",
151 "Africa/Nairobi",
152 "Africa/Ndjamena",
153 "Africa/Niamey",
154 "Africa/Nouakchott",
155 "Africa/Ouagadougou",
156 "Africa/Porto-Novo",
157 "Africa/Sao_Tome",
158 "Africa/Timbuktu",
159 "Africa/Tripoli",
160 "Africa/Tunis",
161 "Africa/Windhoek",
162 "America/Adak",
163 "America/Anchorage",
164 "America/Anguilla",
165 "America/Antigua",
166 "America/Araguaina",
167 "America/Argentina/Buenos_Aires",
168 "America/Argentina/Catamarca",
169 "America/Argentina/ComodRivadavia",
170 "America/Argentina/Cordoba",
171 "America/Argentina/Jujuy",
172 "America/Argentina/La_Rioja",
173 "America/Argentina/Mendoza",
174 "America/Argentina/Rio_Gallegos",
175 "America/Argentina/Salta",
176 "America/Argentina/San_Juan",
177 "America/Argentina/San_Luis",
178 "America/Argentina/Tucuman",
179 "America/Argentina/Ushuaia",
180 "America/Aruba",
181 "America/Asuncion",
182 "America/Atikokan",
183 "America/Atka",
184 "America/Bahia",
185 "America/Bahia_Banderas",
186 "America/Barbados",
187 "America/Belem",
188 "America/Belize",
189 "America/Blanc-Sablon",
190 "America/Boa_Vista",
191 "America/Bogota",
192 "America/Boise",
193 "America/Buenos_Aires",
194 "America/Cambridge_Bay",
195 "America/Campo_Grande",
196 "America/Cancun",
197 "America/Caracas",
198 "America/Catamarca",
199 "America/Cayenne",
200 "America/Cayman",
201 "America/Chicago",
202 "America/Chihuahua",
203 "America/Coral_Harbour",
204 "America/Cordoba",
205 "America/Costa_Rica",
206 "America/Creston",
207 "America/Cuiaba",
208 "America/Curacao",
209 "America/Danmarkshavn",
210 "America/Dawson",
211 "America/Dawson_Creek",
212 "America/Denver",
213 "America/Detroit",
214 "America/Dominica",
215 "America/Edmonton",
216 "America/Eirunepe",
217 "America/El_Salvador",
218 "America/Ensenada",
219 "America/Fort_Nelson",
220 "America/Fort_Wayne",
221 "America/Fortaleza",
222 "America/Glace_Bay",
223 "America/Godthab",
224 "America/Goose_Bay",
225 "America/Grand_Turk",
226 "America/Grenada",
227 "America/Guadeloupe",
228 "America/Guatemala",
229 "America/Guayaquil",
230 "America/Guyana",
231 "America/Halifax",
232 "America/Havana",
233 "America/Hermosillo",
234 "America/Indiana/Indianapolis",
235 "America/Indiana/Knox",
236 "America/Indiana/Marengo",
237 "America/Indiana/Petersburg",
238 "America/Indiana/Tell_City",
239 "America/Indiana/Vevay",
240 "America/Indiana/Vincennes",
241 "America/Indiana/Winamac",
242 "America/Indianapolis",
243 "America/Inuvik",
244 "America/Iqaluit",
245 "America/Jamaica",
246 "America/Jujuy",
247 "America/Juneau",
248 "America/Kentucky/Louisville",
249 "America/Kentucky/Monticello",
250 "America/Knox_IN",
251 "America/Kralendijk",
252 "America/La_Paz",
253 "America/Lima",
254 "America/Los_Angeles",
255 "America/Louisville",
256 "America/Lower_Princes",
257 "America/Maceio",
258 "America/Managua",
259 "America/Manaus",
260 "America/Marigot",
261 "America/Martinique",
262 "America/Matamoros",
263 "America/Mazatlan",
264 "America/Mendoza",
265 "America/Menominee",
266 "America/Merida",
267 "America/Metlakatla",
268 "America/Mexico_City",
269 "America/Miquelon",
270 "America/Moncton",
271 "America/Monterrey",
272 "America/Montevideo",
273 "America/Montreal",
274 "America/Montserrat",
275 "America/Nassau",
276 "America/New_York",
277 "America/Nipigon",
278 "America/Nome",
279 "America/Noronha",
280 "America/North_Dakota/Beulah",
281 "America/North_Dakota/Center",
282 "America/North_Dakota/New_Salem",
283 "America/Nuuk",
284 "America/Ojinaga",
285 "America/Panama",
286 "America/Pangnirtung",
287 "America/Paramaribo",
288 "America/Phoenix",
289 "America/Port-au-Prince",
290 "America/Port_of_Spain",
291 "America/Porto_Acre",
292 "America/Porto_Velho",
293 "America/Puerto_Rico",
294 "America/Punta_Arenas",
295 "America/Rainy_River",
296 "America/Rankin_Inlet",
297 "America/Recife",
298 "America/Regina",
299 "America/Resolute",
300 "America/Rio_Branco",
301 "America/Rosario",
302 "America/Santa_Isabel",
303 "America/Santarem",
304 "America/Santiago",
305 "America/Santo_Domingo",
306 "America/Sao_Paulo",
307 "America/Scoresbysund",
308 "America/Shiprock",
309 "America/Sitka",
310 "America/St_Barthelemy",
311 "America/St_Johns",
312 "America/St_Kitts",
313 "America/St_Lucia",
314 "America/St_Thomas",
315 "America/St_Vincent",
316 "America/Swift_Current",
317 "America/Tegucigalpa",
318 "America/Thule",
319 "America/Thunder_Bay",
320 "America/Tijuana",
321 "America/Toronto",
322 "America/Tortola",
323 "America/Vancouver",
324 "America/Virgin",
325 "America/Whitehorse",
326 "America/Winnipeg",
327 "America/Yakutat",
328 "America/Yellowknife",
329 "Antarctica/Casey",
330 "Antarctica/Davis",
331 "Antarctica/DumontDUrville",
332 "Antarctica/Macquarie",
333 "Antarctica/Mawson",
334 "Antarctica/McMurdo",
335 "Antarctica/Palmer",
336 "Antarctica/Rothera",
337 "Antarctica/South_Pole",
338 "Antarctica/Syowa",
339 "Antarctica/Troll",
340 "Antarctica/Vostok",
341 "Arctic/Longyearbyen",
342 "Asia/Aden",
343 "Asia/Almaty",
344 "Asia/Amman",
345 "Asia/Anadyr",
346 "Asia/Aqtau",
347 "Asia/Aqtobe",
348 "Asia/Ashgabat",
349 "Asia/Ashkhabad",
350 "Asia/Atyrau",
351 "Asia/Baghdad",
352 "Asia/Bahrain",
353 "Asia/Baku",
354 "Asia/Bangkok",
355 "Asia/Barnaul",
356 "Asia/Beirut",
357 "Asia/Bishkek",
358 "Asia/Brunei",
359 "Asia/Calcutta",
360 "Asia/Chita",
361 "Asia/Choibalsan",
362 "Asia/Chongqing",
363 "Asia/Chungking",
364 "Asia/Colombo",
365 "Asia/Dacca",
366 "Asia/Damascus",
367 "Asia/Dhaka",
368 "Asia/Dili",
369 "Asia/Dubai",
370 "Asia/Dushanbe",
371 "Asia/Famagusta",
372 "Asia/Gaza",
373 "Asia/Harbin",
374 "Asia/Hebron",
375 "Asia/Ho_Chi_Minh",
376 "Asia/Hong_Kong",
377 "Asia/Hovd",
378 "Asia/Irkutsk",
379 "Asia/Istanbul",
380 "Asia/Jakarta",
381 "Asia/Jayapura",
382 "Asia/Jerusalem",
383 "Asia/Kabul",
384 "Asia/Kamchatka",
385 "Asia/Karachi",
386 "Asia/Kashgar",
387 "Asia/Kathmandu",
388 "Asia/Katmandu",
389 "Asia/Khandyga",
390 "Asia/Kolkata",
391 "Asia/Krasnoyarsk",
392 "Asia/Kuala_Lumpur",
393 "Asia/Kuching",
394 "Asia/Kuwait",
395 "Asia/Macao",
396 "Asia/Macau",
397 "Asia/Magadan",
398 "Asia/Makassar",
399 "Asia/Manila",
400 "Asia/Muscat",
401 "Asia/Nicosia",
402 "Asia/Novokuznetsk",
403 "Asia/Novosibirsk",
404 "Asia/Omsk",
405 "Asia/Oral",
406 "Asia/Phnom_Penh",
407 "Asia/Pontianak",
408 "Asia/Pyongyang",
409 "Asia/Qatar",
410 "Asia/Qostanay",
411 "Asia/Qyzylorda",
412 "Asia/Rangoon",
413 "Asia/Riyadh",
414 "Asia/Saigon",
415 "Asia/Sakhalin",
416 "Asia/Samarkand",
417 "Asia/Seoul",
418 "Asia/Shanghai",
419 "Asia/Singapore",
420 "Asia/Srednekolymsk",
421 "Asia/Taipei",
422 "Asia/Tashkent",
423 "Asia/Tbilisi",
424 "Asia/Tehran",
425 "Asia/Tel_Aviv",
426 "Asia/Thimbu",
427 "Asia/Thimphu",
428 "Asia/Tokyo",
429 "Asia/Tomsk",
430 "Asia/Ujung_Pandang",
431 "Asia/Ulaanbaatar",
432 "Asia/Ulan_Bator",
433 "Asia/Urumqi",
434 "Asia/Ust-Nera",
435 "Asia/Vientiane",
436 "Asia/Vladivostok",
437 "Asia/Yakutsk",
438 "Asia/Yangon",
439 "Asia/Yekaterinburg",
440 "Asia/Yerevan",
441 "Atlantic/Azores",
442 "Atlantic/Bermuda",
443 "Atlantic/Canary",
444 "Atlantic/Cape_Verde",
445 "Atlantic/Faeroe",
446 "Atlantic/Faroe",
447 "Atlantic/Jan_Mayen",
448 "Atlantic/Madeira",
449 "Atlantic/Reykjavik",
450 "Atlantic/South_Georgia",
451 "Atlantic/St_Helena",
452 "Atlantic/Stanley",
453 "Australia/ACT",
454 "Australia/Adelaide",
455 "Australia/Brisbane",
456 "Australia/Broken_Hill",
457 "Australia/Canberra",
458 "Australia/Currie",
459 "Australia/Darwin",
460 "Australia/Eucla",
461 "Australia/Hobart",
462 "Australia/LHI",
463 "Australia/Lindeman",
464 "Australia/Lord_Howe",
465 "Australia/Melbourne",
466 "Australia/NSW",
467 "Australia/North",
468 "Australia/Perth",
469 "Australia/Queensland",
470 "Australia/South",
471 "Australia/Sydney",
472 "Australia/Tasmania",
473 "Australia/Victoria",
474 "Australia/West",
475 "Australia/Yancowinna",
476 "Brazil/Acre",
477 "Brazil/DeNoronha",
478 "Brazil/East",
479 "Brazil/West",
480 "CET",
481 "CST6CDT",
482 "Canada/Atlantic",
483 "Canada/Central",
484 "Canada/Eastern",
485 "Canada/Mountain",
486 "Canada/Newfoundland",
487 "Canada/Pacific",
488 "Canada/Saskatchewan",
489 "Canada/Yukon",
490 "Chile/Continental",
491 "Chile/EasterIsland",
492 "Cuba",
493 "EET",
494 "EST",
495 "EST5EDT",
496 "Egypt",
497 "Eire",
498 "Etc/GMT",
499 "Etc/GMT+0",
500 "Etc/GMT+1",
501 "Etc/GMT+10",
502 "Etc/GMT+11",
503 "Etc/GMT+12",
504 "Etc/GMT+2",
505 "Etc/GMT+3",
506 "Etc/GMT+4",
507 "Etc/GMT+5",
508 "Etc/GMT+6",
509 "Etc/GMT+7",
510 "Etc/GMT+8",
511 "Etc/GMT+9",
512 "Etc/GMT-0",
513 "Etc/GMT-1",
514 "Etc/GMT-10",
515 "Etc/GMT-11",
516 "Etc/GMT-12",
517 "Etc/GMT-13",
518 "Etc/GMT-14",
519 "Etc/GMT-2",
520 "Etc/GMT-3",
521 "Etc/GMT-4",
522 "Etc/GMT-5",
523 "Etc/GMT-6",
524 "Etc/GMT-7",
525 "Etc/GMT-8",
526 "Etc/GMT-9",
527 "Etc/GMT0",
528 "Etc/Greenwich",
529 "Etc/UCT",
530 "Etc/UTC",
531 "Etc/Universal",
532 "Etc/Zulu",
533 "Europe/Amsterdam",
534 "Europe/Andorra",
535 "Europe/Astrakhan",
536 "Europe/Athens",
537 "Europe/Belfast",
538 "Europe/Belgrade",
539 "Europe/Berlin",
540 "Europe/Bratislava",
541 "Europe/Brussels",
542 "Europe/Bucharest",
543 "Europe/Budapest",
544 "Europe/Busingen",
545 "Europe/Chisinau",
546 "Europe/Copenhagen",
547 "Europe/Dublin",
548 "Europe/Gibraltar",
549 "Europe/Guernsey",
550 "Europe/Helsinki",
551 "Europe/Isle_of_Man",
552 "Europe/Istanbul",
553 "Europe/Jersey",
554 "Europe/Kaliningrad",
555 "Europe/Kiev",
556 "Europe/Kirov",
557 "Europe/Lisbon",
558 "Europe/Ljubljana",
559 "Europe/London",
560 "Europe/Luxembourg",
561 "Europe/Madrid",
562 "Europe/Malta",
563 "Europe/Mariehamn",
564 "Europe/Minsk",
565 "Europe/Monaco",
566 "Europe/Moscow",
567 "Europe/Nicosia",
568 "Europe/Oslo",
569 "Europe/Paris",
570 "Europe/Podgorica",
571 "Europe/Prague",
572 "Europe/Riga",
573 "Europe/Rome",
574 "Europe/Samara",
575 "Europe/San_Marino",
576 "Europe/Sarajevo",
577 "Europe/Saratov",
578 "Europe/Simferopol",
579 "Europe/Skopje",
580 "Europe/Sofia",
581 "Europe/Stockholm",
582 "Europe/Tallinn",
583 "Europe/Tirane",
584 "Europe/Tiraspol",
585 "Europe/Ulyanovsk",
586 "Europe/Uzhgorod",
587 "Europe/Vaduz",
588 "Europe/Vatican",
589 "Europe/Vienna",
590 "Europe/Vilnius",
591 "Europe/Volgograd",
592 "Europe/Warsaw",
593 "Europe/Zagreb",
594 "Europe/Zaporozhye",
595 "Europe/Zurich",
596 "GB",
597 "GB-Eire",
598 "GMT",
599 "GMT+0",
600 "GMT-0",
601 "GMT0",
602 "Greenwich",
603 "HST",
604 "Hongkong",
605 "Iceland",
606 "Indian/Antananarivo",
607 "Indian/Chagos",
608 "Indian/Christmas",
609 "Indian/Cocos",
610 "Indian/Comoro",
611 "Indian/Kerguelen",
612 "Indian/Mahe",
613 "Indian/Maldives",
614 "Indian/Mauritius",
615 "Indian/Mayotte",
616 "Indian/Reunion",
617 "Iran",
618 "Israel",
619 "Jamaica",
620 "Japan",
621 "Kwajalein",
622 "Libya",
623 "MET",
624 "MST",
625 "MST7MDT",
626 "Mexico/BajaNorte",
627 "Mexico/BajaSur",
628 "Mexico/General",
629 "NZ",
630 "NZ-CHAT",
631 "Navajo",
632 "PRC",
633 "PST8PDT",
634 "Pacific/Apia",
635 "Pacific/Auckland",
636 "Pacific/Bougainville",
637 "Pacific/Chatham",
638 "Pacific/Chuuk",
639 "Pacific/Easter",
640 "Pacific/Efate",
641 "Pacific/Enderbury",
642 "Pacific/Fakaofo",
643 "Pacific/Fiji",
644 "Pacific/Funafuti",
645 "Pacific/Galapagos",
646 "Pacific/Gambier",
647 "Pacific/Guadalcanal",
648 "Pacific/Guam",
649 "Pacific/Honolulu",
650 "Pacific/Johnston",
651 "Pacific/Kanton",
652 "Pacific/Kiritimati",
653 "Pacific/Kosrae",
654 "Pacific/Kwajalein",
655 "Pacific/Majuro",
656 "Pacific/Marquesas",
657 "Pacific/Midway",
658 "Pacific/Nauru",
659 "Pacific/Niue",
660 "Pacific/Norfolk",
661 "Pacific/Noumea",
662 "Pacific/Pago_Pago",
663 "Pacific/Palau",
664 "Pacific/Pitcairn",
665 "Pacific/Pohnpei",
666 "Pacific/Ponape",
667 "Pacific/Port_Moresby",
668 "Pacific/Rarotonga",
669 "Pacific/Saipan",
670 "Pacific/Samoa",
671 "Pacific/Tahiti",
672 "Pacific/Tarawa",
673 "Pacific/Tongatapu",
674 "Pacific/Truk",
675 "Pacific/Wake",
676 "Pacific/Wallis",
677 "Pacific/Yap",
678 "Poland",
679 "Portugal",
680 "ROC",
681 "ROK",
682 "Singapore",
683 "Turkey",
684 "UCT",
685 "US/Alaska",
686 "US/Aleutian",
687 "US/Arizona",
688 "US/Central",
689 "US/East-Indiana",
690 "US/Eastern",
691 "US/Hawaii",
692 "US/Indiana-Starke",
693 "US/Michigan",
694 "US/Mountain",
695 "US/Pacific",
696 "US/Samoa",
697 "UTC",
698 "Universal",
699 "W-SU",
700 "WET",
701 "Zulu",
702 nullptr};
703
AllTimeZoneNames()704 std::vector<std::string> AllTimeZoneNames() {
705 std::vector<std::string> names;
706 for (const char* const* namep = kTimeZoneNames; *namep != nullptr; ++namep) {
707 names.push_back(std::string("file:") + *namep);
708 }
709 assert(!names.empty());
710
711 std::mt19937 urbg(42); // a UniformRandomBitGenerator with fixed seed
712 std::shuffle(names.begin(), names.end(), urbg);
713 return names;
714 }
715
TestTimeZone()716 cctz::time_zone TestTimeZone() {
717 cctz::time_zone tz;
718 cctz::load_time_zone("America/Los_Angeles", &tz);
719 return tz;
720 }
721
BM_Zone_LoadUTCTimeZoneFirst(benchmark::State & state)722 void BM_Zone_LoadUTCTimeZoneFirst(benchmark::State& state) {
723 cctz::time_zone tz;
724 cctz::load_time_zone("UTC", &tz); // in case we're first
725 cctz::time_zone::Impl::ClearTimeZoneMapTestOnly();
726 while (state.KeepRunning()) {
727 benchmark::DoNotOptimize(cctz::load_time_zone("UTC", &tz));
728 }
729 }
730 BENCHMARK(BM_Zone_LoadUTCTimeZoneFirst);
731
BM_Zone_LoadUTCTimeZoneLast(benchmark::State & state)732 void BM_Zone_LoadUTCTimeZoneLast(benchmark::State& state) {
733 cctz::time_zone tz;
734 for (const auto& name : AllTimeZoneNames()) {
735 cctz::load_time_zone(name, &tz); // prime cache
736 }
737 while (state.KeepRunning()) {
738 benchmark::DoNotOptimize(cctz::load_time_zone("UTC", &tz));
739 }
740 }
741 BENCHMARK(BM_Zone_LoadUTCTimeZoneLast);
742
BM_Zone_LoadTimeZoneFirst(benchmark::State & state)743 void BM_Zone_LoadTimeZoneFirst(benchmark::State& state) {
744 cctz::time_zone tz = cctz::utc_time_zone(); // in case we're first
745 const std::string name = "file:America/Los_Angeles";
746 while (state.KeepRunning()) {
747 state.PauseTiming();
748 cctz::time_zone::Impl::ClearTimeZoneMapTestOnly();
749 state.ResumeTiming();
750 benchmark::DoNotOptimize(cctz::load_time_zone(name, &tz));
751 }
752 }
753 BENCHMARK(BM_Zone_LoadTimeZoneFirst);
754
BM_Zone_LoadTimeZoneCached(benchmark::State & state)755 void BM_Zone_LoadTimeZoneCached(benchmark::State& state) {
756 cctz::time_zone tz = cctz::utc_time_zone(); // in case we're first
757 cctz::time_zone::Impl::ClearTimeZoneMapTestOnly();
758 const std::string name = "file:America/Los_Angeles";
759 cctz::load_time_zone(name, &tz); // prime cache
760 while (state.KeepRunning()) {
761 benchmark::DoNotOptimize(cctz::load_time_zone(name, &tz));
762 }
763 }
764 BENCHMARK(BM_Zone_LoadTimeZoneCached);
765
BM_Zone_LoadLocalTimeZoneCached(benchmark::State & state)766 void BM_Zone_LoadLocalTimeZoneCached(benchmark::State& state) {
767 cctz::utc_time_zone(); // in case we're first
768 cctz::time_zone::Impl::ClearTimeZoneMapTestOnly();
769 cctz::local_time_zone(); // prime cache
770 while (state.KeepRunning()) {
771 benchmark::DoNotOptimize(cctz::local_time_zone());
772 }
773 }
774 BENCHMARK(BM_Zone_LoadLocalTimeZoneCached);
775
BM_Zone_LoadAllTimeZonesFirst(benchmark::State & state)776 void BM_Zone_LoadAllTimeZonesFirst(benchmark::State& state) {
777 cctz::time_zone tz;
778 const std::vector<std::string> names = AllTimeZoneNames();
779 for (auto index = names.size(); state.KeepRunning(); ++index) {
780 if (index == names.size()) {
781 index = 0;
782 }
783 if (index == 0) {
784 state.PauseTiming();
785 cctz::time_zone::Impl::ClearTimeZoneMapTestOnly();
786 state.ResumeTiming();
787 }
788 benchmark::DoNotOptimize(cctz::load_time_zone(names[index], &tz));
789 }
790 }
791 BENCHMARK(BM_Zone_LoadAllTimeZonesFirst);
792
BM_Zone_LoadAllTimeZonesCached(benchmark::State & state)793 void BM_Zone_LoadAllTimeZonesCached(benchmark::State& state) {
794 cctz::time_zone tz;
795 const std::vector<std::string> names = AllTimeZoneNames();
796 for (const auto& name : names) {
797 cctz::load_time_zone(name, &tz); // prime cache
798 }
799 for (auto index = names.size(); state.KeepRunning(); ++index) {
800 if (index == names.size()) {
801 index = 0;
802 }
803 benchmark::DoNotOptimize(cctz::load_time_zone(names[index], &tz));
804 }
805 }
806 BENCHMARK(BM_Zone_LoadAllTimeZonesCached);
807
BM_Zone_TimeZoneEqualityImplicit(benchmark::State & state)808 void BM_Zone_TimeZoneEqualityImplicit(benchmark::State& state) {
809 cctz::time_zone tz; // implicit UTC
810 while (state.KeepRunning()) {
811 benchmark::DoNotOptimize(tz == tz);
812 }
813 }
814 BENCHMARK(BM_Zone_TimeZoneEqualityImplicit);
815
BM_Zone_TimeZoneEqualityExplicit(benchmark::State & state)816 void BM_Zone_TimeZoneEqualityExplicit(benchmark::State& state) {
817 cctz::time_zone tz = cctz::utc_time_zone(); // explicit UTC
818 while (state.KeepRunning()) {
819 benchmark::DoNotOptimize(tz == tz);
820 }
821 }
822 BENCHMARK(BM_Zone_TimeZoneEqualityExplicit);
823
BM_Zone_UTCTimeZone(benchmark::State & state)824 void BM_Zone_UTCTimeZone(benchmark::State& state) {
825 cctz::time_zone tz;
826 while (state.KeepRunning()) {
827 benchmark::DoNotOptimize(cctz::utc_time_zone());
828 }
829 }
830 BENCHMARK(BM_Zone_UTCTimeZone);
831
832 // In each "ToCivil" benchmark we switch between two instants separated
833 // by at least one transition in order to defeat any internal caching of
834 // previous results (e.g., see local_time_hint_).
835 //
836 // The "UTC" variants use UTC instead of the Google/local time zone.
837
BM_Time_ToCivil_CCTZ(benchmark::State & state)838 void BM_Time_ToCivil_CCTZ(benchmark::State& state) {
839 const cctz::time_zone tz = TestTimeZone();
840 std::chrono::system_clock::time_point tp =
841 std::chrono::system_clock::from_time_t(1384569027);
842 std::chrono::system_clock::time_point tp2 =
843 std::chrono::system_clock::from_time_t(1418962578);
844 while (state.KeepRunning()) {
845 std::swap(tp, tp2);
846 tp += std::chrono::seconds(1);
847 benchmark::DoNotOptimize(cctz::convert(tp, tz));
848 }
849 }
850 BENCHMARK(BM_Time_ToCivil_CCTZ);
851
BM_Time_ToCivil_Libc(benchmark::State & state)852 void BM_Time_ToCivil_Libc(benchmark::State& state) {
853 // No timezone support, so just use localtime.
854 time_t t = 1384569027;
855 time_t t2 = 1418962578;
856 struct tm tm;
857 while (state.KeepRunning()) {
858 std::swap(t, t2);
859 t += 1;
860 #if defined(_WIN32) || defined(_WIN64)
861 benchmark::DoNotOptimize(localtime_s(&tm, &t));
862 #else
863 benchmark::DoNotOptimize(localtime_r(&t, &tm));
864 #endif
865 }
866 }
867 BENCHMARK(BM_Time_ToCivil_Libc);
868
BM_Time_ToCivilUTC_CCTZ(benchmark::State & state)869 void BM_Time_ToCivilUTC_CCTZ(benchmark::State& state) {
870 const cctz::time_zone tz = cctz::utc_time_zone();
871 std::chrono::system_clock::time_point tp =
872 std::chrono::system_clock::from_time_t(1384569027);
873 while (state.KeepRunning()) {
874 tp += std::chrono::seconds(1);
875 benchmark::DoNotOptimize(cctz::convert(tp, tz));
876 }
877 }
878 BENCHMARK(BM_Time_ToCivilUTC_CCTZ);
879
BM_Time_ToCivilUTC_Libc(benchmark::State & state)880 void BM_Time_ToCivilUTC_Libc(benchmark::State& state) {
881 time_t t = 1384569027;
882 struct tm tm;
883 while (state.KeepRunning()) {
884 t += 1;
885 #if defined(_WIN32) || defined(_WIN64)
886 benchmark::DoNotOptimize(gmtime_s(&tm, &t));
887 #else
888 benchmark::DoNotOptimize(gmtime_r(&t, &tm));
889 #endif
890 }
891 }
892 BENCHMARK(BM_Time_ToCivilUTC_Libc);
893
894 // In each "FromCivil" benchmark we switch between two YMDhms values
895 // separated by at least one transition in order to defeat any internal
896 // caching of previous results (e.g., see time_local_hint_).
897 //
898 // The "UTC" variants use UTC instead of the Google/local time zone.
899 // The "Day0" variants require normalization of the day of month.
900
BM_Time_FromCivil_CCTZ(benchmark::State & state)901 void BM_Time_FromCivil_CCTZ(benchmark::State& state) {
902 const cctz::time_zone tz = TestTimeZone();
903 int i = 0;
904 while (state.KeepRunning()) {
905 if ((i++ & 1) == 0) {
906 benchmark::DoNotOptimize(
907 cctz::convert(cctz::civil_second(2014, 12, 18, 20, 16, 18), tz));
908 } else {
909 benchmark::DoNotOptimize(
910 cctz::convert(cctz::civil_second(2013, 11, 15, 18, 30, 27), tz));
911 }
912 }
913 }
914 BENCHMARK(BM_Time_FromCivil_CCTZ);
915
BM_Time_FromCivil_Libc(benchmark::State & state)916 void BM_Time_FromCivil_Libc(benchmark::State& state) {
917 // No timezone support, so just use localtime.
918 int i = 0;
919 while (state.KeepRunning()) {
920 struct tm tm;
921 if ((i++ & 1) == 0) {
922 tm.tm_year = 2014 - 1900;
923 tm.tm_mon = 12 - 1;
924 tm.tm_mday = 18;
925 tm.tm_hour = 20;
926 tm.tm_min = 16;
927 tm.tm_sec = 18;
928 } else {
929 tm.tm_year = 2013 - 1900;
930 tm.tm_mon = 11 - 1;
931 tm.tm_mday = 15;
932 tm.tm_hour = 18;
933 tm.tm_min = 30;
934 tm.tm_sec = 27;
935 }
936 tm.tm_isdst = -1;
937 benchmark::DoNotOptimize(mktime(&tm));
938 }
939 }
940 BENCHMARK(BM_Time_FromCivil_Libc);
941
BM_Time_FromCivilUTC_CCTZ(benchmark::State & state)942 void BM_Time_FromCivilUTC_CCTZ(benchmark::State& state) {
943 const cctz::time_zone tz = cctz::utc_time_zone();
944 while (state.KeepRunning()) {
945 benchmark::DoNotOptimize(
946 cctz::convert(cctz::civil_second(2014, 12, 18, 20, 16, 18), tz));
947 }
948 }
949 BENCHMARK(BM_Time_FromCivilUTC_CCTZ);
950
951 // There is no BM_Time_FromCivilUTC_Libc.
952
BM_Time_FromCivilDay0_CCTZ(benchmark::State & state)953 void BM_Time_FromCivilDay0_CCTZ(benchmark::State& state) {
954 const cctz::time_zone tz = TestTimeZone();
955 int i = 0;
956 while (state.KeepRunning()) {
957 if ((i++ & 1) == 0) {
958 benchmark::DoNotOptimize(
959 cctz::convert(cctz::civil_second(2014, 12, 0, 20, 16, 18), tz));
960 } else {
961 benchmark::DoNotOptimize(
962 cctz::convert(cctz::civil_second(2013, 11, 0, 18, 30, 27), tz));
963 }
964 }
965 }
966 BENCHMARK(BM_Time_FromCivilDay0_CCTZ);
967
BM_Time_FromCivilDay0_Libc(benchmark::State & state)968 void BM_Time_FromCivilDay0_Libc(benchmark::State& state) {
969 // No timezone support, so just use localtime.
970 int i = 0;
971 while (state.KeepRunning()) {
972 struct tm tm;
973 if ((i++ & 1) == 0) {
974 tm.tm_year = 2014 - 1900;
975 tm.tm_mon = 12 - 1;
976 tm.tm_mday = 0;
977 tm.tm_hour = 20;
978 tm.tm_min = 16;
979 tm.tm_sec = 18;
980 } else {
981 tm.tm_year = 2013 - 1900;
982 tm.tm_mon = 11 - 1;
983 tm.tm_mday = 0;
984 tm.tm_hour = 18;
985 tm.tm_min = 30;
986 tm.tm_sec = 27;
987 }
988 tm.tm_isdst = -1;
989 benchmark::DoNotOptimize(mktime(&tm));
990 }
991 }
992 BENCHMARK(BM_Time_FromCivilDay0_Libc);
993
994 const char* const kFormats[] = {
995 RFC1123_full, // 0
996 RFC1123_no_wday, // 1
997 RFC3339_full, // 2
998 RFC3339_sec, // 3
999 "%Y-%m-%d%ET%H:%M:%S", // 4
1000 "%Y-%m-%d", // 5
1001 };
1002 const int kNumFormats = sizeof(kFormats) / sizeof(kFormats[0]);
1003
BM_Format_FormatTime(benchmark::State & state)1004 void BM_Format_FormatTime(benchmark::State& state) {
1005 const std::string fmt = kFormats[state.range(0)];
1006 state.SetLabel(fmt);
1007 const cctz::time_zone tz = TestTimeZone();
1008 const std::chrono::system_clock::time_point tp =
1009 cctz::convert(cctz::civil_second(1977, 6, 28, 9, 8, 7), tz) +
1010 std::chrono::microseconds(1);
1011 while (state.KeepRunning()) {
1012 benchmark::DoNotOptimize(cctz::format(fmt, tp, tz));
1013 }
1014 }
1015 BENCHMARK(BM_Format_FormatTime)->DenseRange(0, kNumFormats - 1);
1016
BM_Format_ParseTime(benchmark::State & state)1017 void BM_Format_ParseTime(benchmark::State& state) {
1018 const std::string fmt = kFormats[state.range(0)];
1019 state.SetLabel(fmt);
1020 const cctz::time_zone tz = TestTimeZone();
1021 std::chrono::system_clock::time_point tp =
1022 cctz::convert(cctz::civil_second(1977, 6, 28, 9, 8, 7), tz) +
1023 std::chrono::microseconds(1);
1024 const std::string when = cctz::format(fmt, tp, tz);
1025 while (state.KeepRunning()) {
1026 benchmark::DoNotOptimize(cctz::parse(fmt, when, tz, &tp));
1027 }
1028 }
1029 BENCHMARK(BM_Format_ParseTime)->DenseRange(0, kNumFormats - 1);
1030
1031 } // namespace
1032