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/Kyiv",
558                                       "Europe/Lisbon",
559                                       "Europe/Ljubljana",
560                                       "Europe/London",
561                                       "Europe/Luxembourg",
562                                       "Europe/Madrid",
563                                       "Europe/Malta",
564                                       "Europe/Mariehamn",
565                                       "Europe/Minsk",
566                                       "Europe/Monaco",
567                                       "Europe/Moscow",
568                                       "Europe/Nicosia",
569                                       "Europe/Oslo",
570                                       "Europe/Paris",
571                                       "Europe/Podgorica",
572                                       "Europe/Prague",
573                                       "Europe/Riga",
574                                       "Europe/Rome",
575                                       "Europe/Samara",
576                                       "Europe/San_Marino",
577                                       "Europe/Sarajevo",
578                                       "Europe/Saratov",
579                                       "Europe/Simferopol",
580                                       "Europe/Skopje",
581                                       "Europe/Sofia",
582                                       "Europe/Stockholm",
583                                       "Europe/Tallinn",
584                                       "Europe/Tirane",
585                                       "Europe/Tiraspol",
586                                       "Europe/Ulyanovsk",
587                                       "Europe/Uzhgorod",
588                                       "Europe/Vaduz",
589                                       "Europe/Vatican",
590                                       "Europe/Vienna",
591                                       "Europe/Vilnius",
592                                       "Europe/Volgograd",
593                                       "Europe/Warsaw",
594                                       "Europe/Zagreb",
595                                       "Europe/Zaporozhye",
596                                       "Europe/Zurich",
597                                       "Factory",
598                                       "GB",
599                                       "GB-Eire",
600                                       "GMT",
601                                       "GMT+0",
602                                       "GMT-0",
603                                       "GMT0",
604                                       "Greenwich",
605                                       "HST",
606                                       "Hongkong",
607                                       "Iceland",
608                                       "Indian/Antananarivo",
609                                       "Indian/Chagos",
610                                       "Indian/Christmas",
611                                       "Indian/Cocos",
612                                       "Indian/Comoro",
613                                       "Indian/Kerguelen",
614                                       "Indian/Mahe",
615                                       "Indian/Maldives",
616                                       "Indian/Mauritius",
617                                       "Indian/Mayotte",
618                                       "Indian/Reunion",
619                                       "Iran",
620                                       "Israel",
621                                       "Jamaica",
622                                       "Japan",
623                                       "Kwajalein",
624                                       "Libya",
625                                       "MET",
626                                       "MST",
627                                       "MST7MDT",
628                                       "Mexico/BajaNorte",
629                                       "Mexico/BajaSur",
630                                       "Mexico/General",
631                                       "NZ",
632                                       "NZ-CHAT",
633                                       "Navajo",
634                                       "PRC",
635                                       "PST8PDT",
636                                       "Pacific/Apia",
637                                       "Pacific/Auckland",
638                                       "Pacific/Bougainville",
639                                       "Pacific/Chatham",
640                                       "Pacific/Chuuk",
641                                       "Pacific/Easter",
642                                       "Pacific/Efate",
643                                       "Pacific/Enderbury",
644                                       "Pacific/Fakaofo",
645                                       "Pacific/Fiji",
646                                       "Pacific/Funafuti",
647                                       "Pacific/Galapagos",
648                                       "Pacific/Gambier",
649                                       "Pacific/Guadalcanal",
650                                       "Pacific/Guam",
651                                       "Pacific/Honolulu",
652                                       "Pacific/Johnston",
653                                       "Pacific/Kanton",
654                                       "Pacific/Kiritimati",
655                                       "Pacific/Kosrae",
656                                       "Pacific/Kwajalein",
657                                       "Pacific/Majuro",
658                                       "Pacific/Marquesas",
659                                       "Pacific/Midway",
660                                       "Pacific/Nauru",
661                                       "Pacific/Niue",
662                                       "Pacific/Norfolk",
663                                       "Pacific/Noumea",
664                                       "Pacific/Pago_Pago",
665                                       "Pacific/Palau",
666                                       "Pacific/Pitcairn",
667                                       "Pacific/Pohnpei",
668                                       "Pacific/Ponape",
669                                       "Pacific/Port_Moresby",
670                                       "Pacific/Rarotonga",
671                                       "Pacific/Saipan",
672                                       "Pacific/Samoa",
673                                       "Pacific/Tahiti",
674                                       "Pacific/Tarawa",
675                                       "Pacific/Tongatapu",
676                                       "Pacific/Truk",
677                                       "Pacific/Wake",
678                                       "Pacific/Wallis",
679                                       "Pacific/Yap",
680                                       "Poland",
681                                       "Portugal",
682                                       "ROC",
683                                       "ROK",
684                                       "Singapore",
685                                       "Turkey",
686                                       "UCT",
687                                       "US/Alaska",
688                                       "US/Aleutian",
689                                       "US/Arizona",
690                                       "US/Central",
691                                       "US/East-Indiana",
692                                       "US/Eastern",
693                                       "US/Hawaii",
694                                       "US/Indiana-Starke",
695                                       "US/Michigan",
696                                       "US/Mountain",
697                                       "US/Pacific",
698                                       "US/Samoa",
699                                       "UTC",
700                                       "Universal",
701                                       "W-SU",
702                                       "WET",
703                                       "Zulu",
704                                       nullptr};
705 
AllTimeZoneNames()706 std::vector<std::string> AllTimeZoneNames() {
707   std::vector<std::string> names;
708   for (const char* const* namep = kTimeZoneNames; *namep != nullptr; ++namep) {
709     names.push_back(std::string("file:") + *namep);
710   }
711   assert(!names.empty());
712 
713   std::mt19937 urbg(42);  // a UniformRandomBitGenerator with fixed seed
714   std::shuffle(names.begin(), names.end(), urbg);
715   return names;
716 }
717 
TestTimeZone()718 cctz::time_zone TestTimeZone() {
719   cctz::time_zone tz;
720   cctz::load_time_zone("America/Los_Angeles", &tz);
721   return tz;
722 }
723 
BM_Zone_LoadUTCTimeZoneFirst(benchmark::State & state)724 void BM_Zone_LoadUTCTimeZoneFirst(benchmark::State& state) {
725   cctz::time_zone tz;
726   cctz::load_time_zone("UTC", &tz);  // in case we're first
727   cctz::time_zone::Impl::ClearTimeZoneMapTestOnly();
728   while (state.KeepRunning()) {
729     benchmark::DoNotOptimize(cctz::load_time_zone("UTC", &tz));
730   }
731 }
732 BENCHMARK(BM_Zone_LoadUTCTimeZoneFirst);
733 
BM_Zone_LoadUTCTimeZoneLast(benchmark::State & state)734 void BM_Zone_LoadUTCTimeZoneLast(benchmark::State& state) {
735   cctz::time_zone tz;
736   for (const auto& name : AllTimeZoneNames()) {
737     cctz::load_time_zone(name, &tz);  // prime cache
738   }
739   while (state.KeepRunning()) {
740     benchmark::DoNotOptimize(cctz::load_time_zone("UTC", &tz));
741   }
742 }
743 BENCHMARK(BM_Zone_LoadUTCTimeZoneLast);
744 
BM_Zone_LoadTimeZoneFirst(benchmark::State & state)745 void BM_Zone_LoadTimeZoneFirst(benchmark::State& state) {
746   cctz::time_zone tz = cctz::utc_time_zone();  // in case we're first
747   const std::string name = "file:America/Los_Angeles";
748   while (state.KeepRunning()) {
749     state.PauseTiming();
750     cctz::time_zone::Impl::ClearTimeZoneMapTestOnly();
751     state.ResumeTiming();
752     benchmark::DoNotOptimize(cctz::load_time_zone(name, &tz));
753   }
754 }
755 BENCHMARK(BM_Zone_LoadTimeZoneFirst);
756 
BM_Zone_LoadTimeZoneCached(benchmark::State & state)757 void BM_Zone_LoadTimeZoneCached(benchmark::State& state) {
758   cctz::time_zone tz = cctz::utc_time_zone();  // in case we're first
759   cctz::time_zone::Impl::ClearTimeZoneMapTestOnly();
760   const std::string name = "file:America/Los_Angeles";
761   cctz::load_time_zone(name, &tz);  // prime cache
762   while (state.KeepRunning()) {
763     benchmark::DoNotOptimize(cctz::load_time_zone(name, &tz));
764   }
765 }
766 BENCHMARK(BM_Zone_LoadTimeZoneCached);
767 
BM_Zone_LoadLocalTimeZoneCached(benchmark::State & state)768 void BM_Zone_LoadLocalTimeZoneCached(benchmark::State& state) {
769   cctz::utc_time_zone();  // in case we're first
770   cctz::time_zone::Impl::ClearTimeZoneMapTestOnly();
771   cctz::local_time_zone();  // prime cache
772   while (state.KeepRunning()) {
773     benchmark::DoNotOptimize(cctz::local_time_zone());
774   }
775 }
776 BENCHMARK(BM_Zone_LoadLocalTimeZoneCached);
777 
BM_Zone_LoadAllTimeZonesFirst(benchmark::State & state)778 void BM_Zone_LoadAllTimeZonesFirst(benchmark::State& state) {
779   cctz::time_zone tz;
780   const std::vector<std::string> names = AllTimeZoneNames();
781   for (auto index = names.size(); state.KeepRunning(); ++index) {
782     if (index == names.size()) {
783       index = 0;
784     }
785     if (index == 0) {
786       state.PauseTiming();
787       cctz::time_zone::Impl::ClearTimeZoneMapTestOnly();
788       state.ResumeTiming();
789     }
790     benchmark::DoNotOptimize(cctz::load_time_zone(names[index], &tz));
791   }
792 }
793 BENCHMARK(BM_Zone_LoadAllTimeZonesFirst);
794 
BM_Zone_LoadAllTimeZonesCached(benchmark::State & state)795 void BM_Zone_LoadAllTimeZonesCached(benchmark::State& state) {
796   cctz::time_zone tz;
797   const std::vector<std::string> names = AllTimeZoneNames();
798   for (const auto& name : names) {
799     cctz::load_time_zone(name, &tz);  // prime cache
800   }
801   for (auto index = names.size(); state.KeepRunning(); ++index) {
802     if (index == names.size()) {
803       index = 0;
804     }
805     benchmark::DoNotOptimize(cctz::load_time_zone(names[index], &tz));
806   }
807 }
808 BENCHMARK(BM_Zone_LoadAllTimeZonesCached);
809 
BM_Zone_TimeZoneEqualityImplicit(benchmark::State & state)810 void BM_Zone_TimeZoneEqualityImplicit(benchmark::State& state) {
811   cctz::time_zone tz;  // implicit UTC
812   while (state.KeepRunning()) {
813     benchmark::DoNotOptimize(tz == tz);
814   }
815 }
816 BENCHMARK(BM_Zone_TimeZoneEqualityImplicit);
817 
BM_Zone_TimeZoneEqualityExplicit(benchmark::State & state)818 void BM_Zone_TimeZoneEqualityExplicit(benchmark::State& state) {
819   cctz::time_zone tz = cctz::utc_time_zone();  // explicit UTC
820   while (state.KeepRunning()) {
821     benchmark::DoNotOptimize(tz == tz);
822   }
823 }
824 BENCHMARK(BM_Zone_TimeZoneEqualityExplicit);
825 
BM_Zone_UTCTimeZone(benchmark::State & state)826 void BM_Zone_UTCTimeZone(benchmark::State& state) {
827   cctz::time_zone tz;
828   while (state.KeepRunning()) {
829     benchmark::DoNotOptimize(cctz::utc_time_zone());
830   }
831 }
832 BENCHMARK(BM_Zone_UTCTimeZone);
833 
834 // In each "ToCivil" benchmark we switch between two instants separated
835 // by at least one transition in order to defeat any internal caching of
836 // previous results (e.g., see local_time_hint_).
837 //
838 // The "UTC" variants use UTC instead of the Google/local time zone.
839 
BM_Time_ToCivil_CCTZ(benchmark::State & state)840 void BM_Time_ToCivil_CCTZ(benchmark::State& state) {
841   const cctz::time_zone tz = TestTimeZone();
842   std::chrono::system_clock::time_point tp =
843       std::chrono::system_clock::from_time_t(1384569027);
844   std::chrono::system_clock::time_point tp2 =
845       std::chrono::system_clock::from_time_t(1418962578);
846   while (state.KeepRunning()) {
847     std::swap(tp, tp2);
848     tp += std::chrono::seconds(1);
849     benchmark::DoNotOptimize(cctz::convert(tp, tz));
850   }
851 }
852 BENCHMARK(BM_Time_ToCivil_CCTZ);
853 
BM_Time_ToCivil_Libc(benchmark::State & state)854 void BM_Time_ToCivil_Libc(benchmark::State& state) {
855   // No timezone support, so just use localtime.
856   time_t t = 1384569027;
857   time_t t2 = 1418962578;
858   struct tm tm;
859   while (state.KeepRunning()) {
860     std::swap(t, t2);
861     t += 1;
862 #if defined(_WIN32) || defined(_WIN64)
863     benchmark::DoNotOptimize(localtime_s(&tm, &t));
864 #else
865     benchmark::DoNotOptimize(localtime_r(&t, &tm));
866 #endif
867   }
868 }
869 BENCHMARK(BM_Time_ToCivil_Libc);
870 
BM_Time_ToCivilUTC_CCTZ(benchmark::State & state)871 void BM_Time_ToCivilUTC_CCTZ(benchmark::State& state) {
872   const cctz::time_zone tz = cctz::utc_time_zone();
873   std::chrono::system_clock::time_point tp =
874       std::chrono::system_clock::from_time_t(1384569027);
875   while (state.KeepRunning()) {
876     tp += std::chrono::seconds(1);
877     benchmark::DoNotOptimize(cctz::convert(tp, tz));
878   }
879 }
880 BENCHMARK(BM_Time_ToCivilUTC_CCTZ);
881 
BM_Time_ToCivilUTC_Libc(benchmark::State & state)882 void BM_Time_ToCivilUTC_Libc(benchmark::State& state) {
883   time_t t = 1384569027;
884   struct tm tm;
885   while (state.KeepRunning()) {
886     t += 1;
887 #if defined(_WIN32) || defined(_WIN64)
888     benchmark::DoNotOptimize(gmtime_s(&tm, &t));
889 #else
890     benchmark::DoNotOptimize(gmtime_r(&t, &tm));
891 #endif
892   }
893 }
894 BENCHMARK(BM_Time_ToCivilUTC_Libc);
895 
896 // In each "FromCivil" benchmark we switch between two YMDhms values
897 // separated by at least one transition in order to defeat any internal
898 // caching of previous results (e.g., see time_local_hint_).
899 //
900 // The "UTC" variants use UTC instead of the Google/local time zone.
901 // The "Day0" variants require normalization of the day of month.
902 
BM_Time_FromCivil_CCTZ(benchmark::State & state)903 void BM_Time_FromCivil_CCTZ(benchmark::State& state) {
904   const cctz::time_zone tz = TestTimeZone();
905   int i = 0;
906   while (state.KeepRunning()) {
907     if ((i++ & 1) == 0) {
908       benchmark::DoNotOptimize(
909           cctz::convert(cctz::civil_second(2014, 12, 18, 20, 16, 18), tz));
910     } else {
911       benchmark::DoNotOptimize(
912           cctz::convert(cctz::civil_second(2013, 11, 15, 18, 30, 27), tz));
913     }
914   }
915 }
916 BENCHMARK(BM_Time_FromCivil_CCTZ);
917 
BM_Time_FromCivil_Libc(benchmark::State & state)918 void BM_Time_FromCivil_Libc(benchmark::State& state) {
919   // No timezone support, so just use localtime.
920   int i = 0;
921   while (state.KeepRunning()) {
922     struct tm tm;
923     if ((i++ & 1) == 0) {
924       tm.tm_year = 2014 - 1900;
925       tm.tm_mon = 12 - 1;
926       tm.tm_mday = 18;
927       tm.tm_hour = 20;
928       tm.tm_min = 16;
929       tm.tm_sec = 18;
930     } else {
931       tm.tm_year = 2013 - 1900;
932       tm.tm_mon = 11 - 1;
933       tm.tm_mday = 15;
934       tm.tm_hour = 18;
935       tm.tm_min = 30;
936       tm.tm_sec = 27;
937     }
938     tm.tm_isdst = -1;
939     benchmark::DoNotOptimize(mktime(&tm));
940   }
941 }
942 BENCHMARK(BM_Time_FromCivil_Libc);
943 
BM_Time_FromCivilUTC_CCTZ(benchmark::State & state)944 void BM_Time_FromCivilUTC_CCTZ(benchmark::State& state) {
945   const cctz::time_zone tz = cctz::utc_time_zone();
946   while (state.KeepRunning()) {
947     benchmark::DoNotOptimize(
948         cctz::convert(cctz::civil_second(2014, 12, 18, 20, 16, 18), tz));
949   }
950 }
951 BENCHMARK(BM_Time_FromCivilUTC_CCTZ);
952 
953 // There is no BM_Time_FromCivilUTC_Libc.
954 
BM_Time_FromCivilDay0_CCTZ(benchmark::State & state)955 void BM_Time_FromCivilDay0_CCTZ(benchmark::State& state) {
956   const cctz::time_zone tz = TestTimeZone();
957   int i = 0;
958   while (state.KeepRunning()) {
959     if ((i++ & 1) == 0) {
960       benchmark::DoNotOptimize(
961           cctz::convert(cctz::civil_second(2014, 12, 0, 20, 16, 18), tz));
962     } else {
963       benchmark::DoNotOptimize(
964           cctz::convert(cctz::civil_second(2013, 11, 0, 18, 30, 27), tz));
965     }
966   }
967 }
968 BENCHMARK(BM_Time_FromCivilDay0_CCTZ);
969 
BM_Time_FromCivilDay0_Libc(benchmark::State & state)970 void BM_Time_FromCivilDay0_Libc(benchmark::State& state) {
971   // No timezone support, so just use localtime.
972   int i = 0;
973   while (state.KeepRunning()) {
974     struct tm tm;
975     if ((i++ & 1) == 0) {
976       tm.tm_year = 2014 - 1900;
977       tm.tm_mon = 12 - 1;
978       tm.tm_mday = 0;
979       tm.tm_hour = 20;
980       tm.tm_min = 16;
981       tm.tm_sec = 18;
982     } else {
983       tm.tm_year = 2013 - 1900;
984       tm.tm_mon = 11 - 1;
985       tm.tm_mday = 0;
986       tm.tm_hour = 18;
987       tm.tm_min = 30;
988       tm.tm_sec = 27;
989     }
990     tm.tm_isdst = -1;
991     benchmark::DoNotOptimize(mktime(&tm));
992   }
993 }
994 BENCHMARK(BM_Time_FromCivilDay0_Libc);
995 
996 const char* const kFormats[] = {
997     RFC1123_full,           // 0
998     RFC1123_no_wday,        // 1
999     RFC3339_full,           // 2
1000     RFC3339_sec,            // 3
1001     "%Y-%m-%d%ET%H:%M:%S",  // 4
1002     "%Y-%m-%d",             // 5
1003 };
1004 const int kNumFormats = sizeof(kFormats) / sizeof(kFormats[0]);
1005 
BM_Format_FormatTime(benchmark::State & state)1006 void BM_Format_FormatTime(benchmark::State& state) {
1007   const std::string fmt = kFormats[state.range(0)];
1008   state.SetLabel(fmt);
1009   const cctz::time_zone tz = TestTimeZone();
1010   const std::chrono::system_clock::time_point tp =
1011       cctz::convert(cctz::civil_second(1977, 6, 28, 9, 8, 7), tz) +
1012       std::chrono::microseconds(1);
1013   while (state.KeepRunning()) {
1014     benchmark::DoNotOptimize(cctz::format(fmt, tp, tz));
1015   }
1016 }
1017 BENCHMARK(BM_Format_FormatTime)->DenseRange(0, kNumFormats - 1);
1018 
BM_Format_ParseTime(benchmark::State & state)1019 void BM_Format_ParseTime(benchmark::State& state) {
1020   const std::string fmt = kFormats[state.range(0)];
1021   state.SetLabel(fmt);
1022   const cctz::time_zone tz = TestTimeZone();
1023   std::chrono::system_clock::time_point tp =
1024       cctz::convert(cctz::civil_second(1977, 6, 28, 9, 8, 7), tz) +
1025       std::chrono::microseconds(1);
1026   const std::string when = cctz::format(fmt, tp, tz);
1027   while (state.KeepRunning()) {
1028     benchmark::DoNotOptimize(cctz::parse(fmt, when, tz, &tp));
1029   }
1030 }
1031 BENCHMARK(BM_Format_ParseTime)->DenseRange(0, kNumFormats - 1);
1032 
1033 }  // namespace
1034