测试mktime和localtime_r性能及优化方法


点击(此处)折叠或打开

  1. // 测试mktime和localtime_r性能及优化方法
  2. //
  3. // 编译方法:g++ -g -o x x.cpp或g++ -O2 -o x x.cpp,两种编译方式性能基本相同。
  4. //
  5. // 结论:
  6. // 1) 环境变量TZ和isdst均不影响localtime_r的性能(第一次调用了除外)
  7. // 2) 环境变量TZ严重影响localtime的性能
  8. // 3) 环境变量TZ和isdst均会严重影响mktime的性能
  9. // *4) 注意mktime的参数即是输入参数也是输出参数,它会修改isdst值
  10. // *5) 另外需要注意localtime_r为非信号安全函数,
  11. // 不能在信号处理过程中调用,否则可能发生死锁等问题
  12. //
  13. // 64位机器性能数据(与32位CPU不同):
  14. /*
  15. $ ./x 1000000
  16. test: localtime ...
  17. TZ is NULL: 2457ms
  18. TZ is empty: 172ms
  19. TZ is Asia/Shanghai: 173ms

  20. test: localtime_r ...
  21. TZ is NULL and isdst=1: 125ms
  22. TZ is NULL and isdst=0: 125ms
  23. TZ is NULL and isdst=-1: 125ms
  24. TZ is NULL and isdst undefined: 125ms
  25. TZ is empty and isdst=1: 125ms
  26. TZ is empty and isdst=0: 125ms
  27. TZ is empty and isdst=-1: 125ms
  28. TZ is empty and isdst undefined: 127ms
  29. TZ is Asia/Shanghai and isdst=1: 126ms
  30. TZ is Asia/Shanghai and isdst=0: 125ms
  31. TZ is Asia/Shanghai and isdst=-1: 125ms
  32. TZ is Asia/Shanghai and isdst undefined: 125ms

  33. test: mktime ...
  34. TZ is NULL and isdst=1: 635841ms
  35. TZ is NULL and isdst=0: 2583ms
  36. TZ is NULL and isdst=-1: 2596ms
  37. TZ is NULL and isdst undefined: 2579ms
  38. TZ is empty and isdst=1: 122377ms
  39. TZ is empty and isdst=0: 229ms
  40. TZ is empty and isdst=-1: 230ms
  41. TZ is empty and isdst undefined: 229ms
  42. TZ is Asia/Shanghai and isdst=1: 122536ms
  43. TZ is Asia/Shanghai and isdst=0: 228ms
  44. TZ is Asia/Shanghai and isdst=-1: 230ms
  45. TZ is Asia/Shanghai and isdst undefined: 228ms
  46. */

  47. // 32位机器性能数据(与64位CPU不同):
  48. /*
  49. $ ./x 1000000
  50. test: localtime ...
  51. TZ is NULL: 1445ms
  52. TZ is empty: 252ms
  53. TZ is Asia/Shanghai: 252ms

  54. test: localtime_r ...
  55. TZ is NULL and isdst=1: 161ms
  56. TZ is NULL and isdst=0: 160ms
  57. TZ is NULL and isdst=-1: 161ms
  58. TZ is NULL and isdst undefined: 161ms
  59. TZ is empty and isdst=1: 160ms
  60. TZ is empty and isdst=0: 161ms
  61. TZ is empty and isdst=-1: 161ms
  62. TZ is empty and isdst undefined: 161ms
  63. TZ is Asia/Shanghai and isdst=1: 161ms
  64. TZ is Asia/Shanghai and isdst=0: 161ms
  65. TZ is Asia/Shanghai and isdst=-1: 161ms
  66. TZ is Asia/Shanghai and isdst undefined: 161ms

  67. test: mktime ...
  68. TZ is NULL and isdst=1: 199375ms
  69. TZ is NULL and isdst=0: 1488ms
  70. TZ is NULL and isdst=-1: 1483ms
  71. TZ is NULL and isdst undefined: 1497ms
  72. TZ is empty and isdst=1: 161057ms
  73. TZ is empty and isdst=0: 325ms
  74. TZ is empty and isdst=-1: 328ms
  75. TZ is empty and isdst undefined: 326ms
  76. TZ is Asia/Shanghai and isdst=1: 161558ms
  77. TZ is Asia/Shanghai and isdst=0: 321ms
  78. TZ is Asia/Shanghai and isdst=-1: 335ms
  79. TZ is Asia/Shanghai and isdst undefined: 328ms
  80. */
  81. // localtime_r相关源代码:
  82. /*
  83. // The C Standard says that localtime and gmtime return the same pointer.
  84. struct tm _tmbuf; // 全局变量

  85. struct tm * __localtime_r (t, tp)
  86.      const time_t *t;
  87.      struct tm *tp;
  88. {
  89.   return __tz_convert (t, 1, tp);
  90. }

  91. // 非线程安全版本,用到了全局变量_tmbuf
  92. struct tm * localtime(t)
  93.      const time_t *t;
  94. {
  95.   return __tz_convert (t, 1, &_tmbuf);
  96. }

  97. struct tm * __tz_convert (const time_t *timer, int use_localtime, struct tm *tp)
  98. {
  99.   。。。
  100.   // 信号处理函数中调用非信号安全函数,可能造成死锁的地方
  101.   __libc_lock_lock (tzset_lock);
  102.   
  103.   // localtime_r未用到_tmbuf,只是localtime使用它!!!
  104.   // 因此对于localtime_r,传递给tzset_internal的第一个参数总是为0(tp != &_tmpbuf),
  105.   // 而对于localtime,它传递给tzset_internal的第一个参数总是为1
  106.   tzset_internal (tp == &_tmbuf && use_localtime, 1);
  107.   。。。
  108. }

  109. // 决定性能的函数,原因是可能涉及文件操作,
  110. // 因此要想提升性能,则应当想办法避免操作文件!!!
  111. static void internal_function
  112. tzset_internal (always, explicit)
  113.      int always;
  114.      int explicit;
  115. {
  116.   static int is_initialized; // 静态变量
  117.   const char *tz;

  118.   // 对于mktime,参数always值总是为1
  119.   // 对于localtime,参数always值总是为1
  120.   // 对于localtime_r,参数always值总是为0
  121.   if (is_initialized && !always)
  122.     return; // 对于localtime_r第一次调用后,后续都在这里直接返回!
  123.   is_initialized = 1;

  124.   tz = getenv ("TZ");
  125.   if (tz == NULL && !explicit)
  126.     tz = TZDEFAULT;
  127.   if (tz && *tz == '\0')
  128.     tz = "Universal";
  129.   if (tz && *tz == ':')
  130.     ++tz;

  131.   // 如果不设置环境变量TZ,则下面这个if语句总是不成立!!!
  132.   // 因此只有设置了环境变量TZ,才有可能在这里直接返回而不进入读文件操作__tzfile_read
  133.   if (old_tz != NULL && tz != NULL && strcmp (tz, old_tz) == 0)
  134.     return; // 在这里返回则可以避免走到文件操作__tzfile_read
  135.   if (tz == NULL)
  136.     tz = TZDEFAULT;

  137.   tz_rules[0].name = NULL;
  138.   tz_rules[1].name = NULL;

  139.   // Save the value of `tz'.
  140.   free (old_tz);
  141.   old_tz = tz ? __strdup (tz) : NULL;

  142.   // 读文件,性能慢的原因
  143.   __tzfile_read (tz, 0, NULL); // Try to read a data file.
  144.   if (__use_tzfile)
  145.     return;
  146.   。。。
  147. }
  148. */
  149. // mktime相关源代码:
  150. /*
  151. time_t mktime (struct tm *tp)
  152. {
  153. #ifdef _LIBC
  154.   // POSIX.1 8.1.1 requires that whenever mktime() is called, the
  155.   // time zone names contained in the external variable 'tzname' shall
  156.   // be set as if the tzset() function had been called.
  157.   __tzset ();
  158. #endif

  159.   // __mktime_internal会调用localtime_r,
  160.   // isdst的取值在这里会严重影响到mktime的性能
  161.   return __mktime_internal (tp, __localtime_r, &localtime_offset);
  162. }

  163. void __tzset (void)
  164. {
  165.   __libc_lock_lock (tzset_lock);

  166.   // 和localtime_r一样也会调用tzset_internal
  167.   tzset_internal (1, 1);

  168.   if (!__use_tzfile)
  169.     {
  170.       // Set `tzname'.
  171.       __tzname[0] = (char *) tz_rules[0].name;
  172.       __tzname[1] = (char *) tz_rules[1].name;
  173.     }

  174.   __libc_lock_unlock (tzset_lock);
  175. }
  176. */
  177. #include stdlib.h>
  178. #include stdio.h>
  179. #include string.h>
  180. #include sys/time.h>
  181. #include time.h>

  182. static void test_localtime(int M); // 测试localtime性能
  183. static void test_localtime_r(int M); // 测试localtime_r性能
  184. static void test_mktime(int M); // 测试mktime性能

  185. int main(int argc, char* argv[])
  186. {
  187.     const int M = (argc2)? 1000000: atoi(argv[1]);

  188.     test_localtime(M);
  189.     printf("\n");
  190.     test_localtime_r(M);
  191.     printf("\n");
  192.     test_mktime(M);

  193.     return 0;
  194. }

  195. // test_localtime
  196. void test_localtime(int M)
  197. {
  198.     int i;
  199.     time_t now = time(NULL);
  200.     struct timeval tv1, tv2;

  201.     printf("test: localtime ...\n");
  202.     unsetenv("TZ");

  203.     // test1
  204.     {
  205.         struct tm* result1;
  206.         gettimeofday(&tv1, NULL);
  207.         for (i=0; iM; ++i)
  208.         {
  209.             result1 = localtime(&now);
  210.         }
  211.         gettimeofday(&tv2, NULL);
  212.         printf("TZ is NULL: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  213.     }
  214.     
  215.     setenv("TZ", "", 0);

  216.     // test2
  217.     {
  218.         struct tm* result2;
  219.         gettimeofday(&tv1, NULL);
  220.         for (i=0; iM; ++i)
  221.         {
  222.             result2 = localtime(&now);
  223.         }
  224.         gettimeofday(&tv2, NULL);
  225.         printf("TZ is empty: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  226.     }

  227.     setenv("TZ", "Asia/Shanghai", 0);

  228.     // test3
  229.     {
  230.         struct tm* result3;
  231.         gettimeofday(&tv1, NULL);
  232.         for (i=0; iM; ++i)
  233.         {
  234.             result3 = localtime(&now);
  235.         }
  236.         gettimeofday(&tv2, NULL);
  237.         printf("TZ is Asia/Shanghai: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  238.     }
  239. }

  240. // test_localtime_r
  241. void test_localtime_r(int M)
  242. {
  243.     int i;
  244.     time_t now = time(NULL);
  245.     struct timeval tv1, tv2;

  246.     printf("test: localtime_r ...\n");
  247.     unsetenv("TZ");

  248.     // test1
  249.     {
  250.         struct tm result1;
  251.         gettimeofday(&tv1, NULL);
  252.         for (i=0; iM; ++i)
  253.         {
  254.             struct tm result1_;
  255.             memcpy(&result1_, &result1, sizeof(result1_));
  256.             result1_.tm_isdst = 1;
  257.             localtime_r(&now, &result1_);
  258.         }
  259.         gettimeofday(&tv2, NULL);
  260.         printf("TZ is NULL and isdst=1: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  261.     }

  262.     // test2
  263.     {
  264.         struct tm result2;
  265.         gettimeofday(&tv1, NULL);
  266.         for (i=0; iM; ++i)
  267.         {
  268.             struct tm result2_;
  269.             memcpy(&result2_, &result2, sizeof(result2_));
  270.             result2_.tm_isdst = 0;
  271.             localtime_r(&now, &result2_);
  272.         }
  273.         gettimeofday(&tv2, NULL);
  274.         printf("TZ is NULL and isdst=0: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  275.     }

  276.     // test3
  277.     {
  278.         struct tm result3;
  279.         gettimeofday(&tv1, NULL);
  280.         for (i=0; iM; ++i)
  281.         {
  282.             struct tm result3_;
  283.             memcpy(&result3_, &result3, sizeof(result3_));
  284.             result3_.tm_isdst = -1;
  285.             localtime_r(&now, &result3_);
  286.         }
  287.         gettimeofday(&tv2, NULL);
  288.         printf("TZ is NULL and isdst=-1: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  289.     }

  290.     // test4
  291.     {
  292.         struct tm result4;
  293.         gettimeofday(&tv1, NULL);
  294.         for (i=0; iM; ++i)
  295.         {
  296.             struct tm result4_;
  297.             memcpy(&result4_, &result4, sizeof(result4_));
  298.             localtime_r(&now, &result4_);
  299.         }
  300.         gettimeofday(&tv2, NULL);
  301.         printf("TZ is NULL and isdst undefined: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  302.     }

  303.     setenv("TZ", "", 0);

  304.     // test5
  305.     {
  306.         struct tm result5;
  307.         gettimeofday(&tv1, NULL);
  308.         for (i=0; iM; ++i)
  309.         {
  310.             struct tm result5_;
  311.             memcpy(&result5_, &result5, sizeof(result5_));
  312.             result5_.tm_isdst = 1;
  313.             localtime_r(&now, &result5_);
  314.         }
  315.         gettimeofday(&tv2, NULL);
  316.         printf("TZ is empty and isdst=1: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  317.     }

  318.     // test6
  319.     {
  320.         struct tm result6;
  321.         gettimeofday(&tv1, NULL);
  322.         for (i=0; iM; ++i)
  323.         {
  324.             struct tm result6_;
  325.             memcpy(&result6_, &result6, sizeof(result6_));
  326.             result6_.tm_isdst = 0;
  327.             localtime_r(&now, &result6_);
  328.         }
  329.         gettimeofday(&tv2, NULL);
  330.         printf("TZ is empty and isdst=0: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  331.     }

  332.     // test7
  333.     {
  334.         struct tm result7;
  335.         gettimeofday(&tv1, NULL);
  336.         for (i=0; iM; ++i)
  337.         {
  338.             struct tm result7_;
  339.             memcpy(&result7_, &result7, sizeof(result7_));
  340.             result7_.tm_isdst = -1;
  341.             localtime_r(&now, &result7_);
  342.         }
  343.         gettimeofday(&tv2, NULL);
  344.         printf("TZ is empty and isdst=-1: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  345.     }

  346.     // test8
  347.     {
  348.         struct tm result8;
  349.         gettimeofday(&tv1, NULL);
  350.         for (i=0; iM; ++i)
  351.         {
  352.             struct tm result8_;
  353.             memcpy(&result8_, &result8, sizeof(result8_));
  354.             result8_.tm_isdst = -1;
  355.             localtime_r(&now, &result8_);
  356.         }
  357.         gettimeofday(&tv2, NULL);
  358.         printf("TZ is empty and isdst undefined: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  359.     }

  360.     setenv("TZ", "Asia/Shanghai", 0);

  361.     // test9
  362.     {
  363.         struct tm result9;
  364.         gettimeofday(&tv1, NULL);
  365.         for (i=0; iM; ++i)
  366.         {
  367.             struct tm result9_;
  368.             memcpy(&result9_, &result9, sizeof(result9_));
  369.             result9_.tm_isdst = 1;
  370.             localtime_r(&now, &result9_);
  371.         }
  372.         gettimeofday(&tv2, NULL);
  373.         printf("TZ is Asia/Shanghai and isdst=1: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  374.     }

  375.     // test10
  376.     {
  377.         struct tm result10;
  378.         gettimeofday(&tv1, NULL);
  379.         for (i=0; iM; ++i)
  380.         {
  381.             struct tm result10_;
  382.             memcpy(&result10_, &result10, sizeof(result10_));
  383.             result10_.tm_isdst = 0;
  384.             localtime_r(&now, &result10_);
  385.         }
  386.         gettimeofday(&tv2, NULL);
  387.         printf("TZ is Asia/Shanghai and isdst=0: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  388.     }

  389.     // test11
  390.     {
  391.         struct tm result11;
  392.         gettimeofday(&tv1, NULL);
  393.         for (i=0; iM; ++i)
  394.         {
  395.             struct tm result11_;
  396.             memcpy(&result11_, &result11, sizeof(result11_));
  397.             result11_.tm_isdst = -1;
  398.             localtime_r(&now, &result11_);
  399.         }
  400.         gettimeofday(&tv2, NULL);
  401.         printf("TZ is Asia/Shanghai and isdst=-1: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  402.     }

  403.     // test12
  404.     {
  405.         struct tm result12;
  406.         gettimeofday(&tv1, NULL);
  407.         for (i=0; iM; ++i)
  408.         {
  409.             struct tm result12_;
  410.             memcpy(&result12_, &result12, sizeof(result12_));
  411.             localtime_r(&now, &result12_);
  412.         }
  413.         gettimeofday(&tv2, NULL);
  414.         printf("TZ is Asia/Shanghai and isdst undefined: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  415.     }
  416. }

  417. // test_mktime
  418. void test_mktime(int M)
  419. {
  420.     int i;
  421.     time_t now = time(NULL);
  422.     struct timeval tv1, tv2;

  423.     printf("test: mktime ...\n");
  424.     unsetenv("TZ");

  425.     // test1
  426.     {
  427.         struct tm result1;
  428.         localtime_r(&now, &result1);
  429.         gettimeofday(&tv1, NULL);
  430.         for (i=0; iM; ++i)
  431.         {
  432.             struct tm result1_;
  433.             memcpy(&result1_, &result1, sizeof(result1_));
  434.             result1_.tm_isdst = 1;
  435.             mktime(&result1_);
  436.         }
  437.         gettimeofday(&tv2, NULL);
  438.         printf("TZ is NULL and isdst=1: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  439.     }

  440.     // test2
  441.     {
  442.         struct tm result2;
  443.         localtime_r(&now, &result2);
  444.         gettimeofday(&tv1, NULL);
  445.         for (i=0; iM; ++i)
  446.         {
  447.             struct tm result2_;
  448.             memcpy(&result2_, &result2, sizeof(result2_));
  449.             result2_.tm_isdst = 0;
  450.             mktime(&result2_);
  451.         }
  452.         gettimeofday(&tv2, NULL);
  453.         printf("TZ is NULL and isdst=0: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  454.     }

  455.     // test3
  456.     {
  457.         struct tm result3;
  458.         localtime_r(&now, &result3);
  459.         gettimeofday(&tv1, NULL);
  460.         for (i=0; iM; ++i)
  461.         {
  462.             struct tm result3_;
  463.             memcpy(&result3_, &result3, sizeof(result3_));
  464.             result3_.tm_isdst = -1;
  465.             mktime(&result3_);
  466.         }
  467.         gettimeofday(&tv2, NULL);
  468.         printf("TZ is NULL and isdst=-1: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  469.     }

  470.     // test4
  471.     {
  472.         struct tm result4;
  473.         localtime_r(&now, &result4);
  474.         gettimeofday(&tv1, NULL);
  475.         for (i=0; iM; ++i)
  476.         {
  477.             struct tm result4_;
  478.             memcpy(&result4_, &result4, sizeof(result4_));
  479.             mktime(&result4_);
  480.         }
  481.         gettimeofday(&tv2, NULL);
  482.         printf("TZ is NULL and isdst undefined: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  483.     }

  484.     setenv("TZ", "", 0);

  485.     // test5
  486.     {
  487.         struct tm result5;
  488.         localtime_r(&now, &result5);
  489.         gettimeofday(&tv1, NULL);
  490.         for (i=0; iM; ++i)
  491.         {
  492.             struct tm result5_;
  493.             memcpy(&result5_, &result5, sizeof(result5_));
  494.             result5_.tm_isdst = 1;
  495.             mktime(&result5_);
  496.         }
  497.         gettimeofday(&tv2, NULL);
  498.         printf("TZ is empty and isdst=1: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  499.     }

  500.     // test6
  501.     {
  502.         struct tm result6;
  503.         localtime_r(&now, &result6);
  504.         gettimeofday(&tv1, NULL);
  505.         for (i=0; iM; ++i)
  506.         {
  507.             struct tm result6_;
  508.             memcpy(&result6_, &result6, sizeof(result6_));
  509.             result6_.tm_isdst = 0;
  510.             mktime(&result6_);
  511.         }
  512.         gettimeofday(&tv2, NULL);
  513.         printf("TZ is empty and isdst=0: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  514.     }

  515.     // test7
  516.     {
  517.         struct tm result7;
  518.         localtime_r(&now, &result7);
  519.         gettimeofday(&tv1, NULL);
  520.         for (i=0; iM; ++i)
  521.         {
  522.             struct tm result7_;
  523.             memcpy(&result7_, &result7, sizeof(result7_));
  524.             result7_.tm_isdst = -1;
  525.             mktime(&result7_);
  526.         }
  527.         gettimeofday(&tv2, NULL);
  528.         printf("TZ is empty and isdst=-1: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  529.     }

  530.     // test8
  531.     {
  532.         struct tm result8;
  533.         localtime_r(&now, &result8);
  534.         gettimeofday(&tv1, NULL);
  535.         for (i=0; iM; ++i)
  536.         {
  537.             struct tm result8_;
  538.             memcpy(&result8_, &result8, sizeof(result8_));
  539.             mktime(&result8_);
  540.         }
  541.         gettimeofday(&tv2, NULL);
  542.         printf("TZ is empty and isdst undefined: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  543.     }

  544.     setenv("TZ", "Asia/Shanghai", 0);

  545.     // test9
  546.     {
  547.         struct tm result9;
  548.         localtime_r(&now, &result9);
  549.         gettimeofday(&tv1, NULL);
  550.         for (i=0; iM; ++i)
  551.         {
  552.             struct tm result9_;
  553.             memcpy(&result9_, &result9, sizeof(result9_));
  554.             result9_.tm_isdst = 1;
  555.             mktime(&result9_);
  556.         }
  557.         gettimeofday(&tv2, NULL);
  558.         printf("TZ is Asia/Shanghai and isdst=1: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  559.     }

  560.     // test10
  561.     {
  562.         struct tm result10;
  563.         localtime_r(&now, &result10);
  564.         gettimeofday(&tv1, NULL);
  565.         for (i=0; iM; ++i)
  566.         {
  567.             struct tm result10_;
  568.             memcpy(&result10_, &result10, sizeof(result10_));
  569.             result10_.tm_isdst = 0;
  570.             mktime(&result10_);
  571.         }
  572.         gettimeofday(&tv2, NULL);
  573.         printf("TZ is Asia/Shanghai and isdst=0: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  574.     }

  575.     // test11
  576.     {
  577.         struct tm result11;
  578.         localtime_r(&now, &result11);
  579.         gettimeofday(&tv1, NULL);
  580.         for (i=0; iM; ++i)
  581.         {
  582.             struct tm result11_;
  583.             memcpy(&result11_, &result11, sizeof(result11_));
  584.             result11_.tm_isdst = -1;
  585.             mktime(&result11_);
  586.         }
  587.         gettimeofday(&tv2, NULL);
  588.         printf("TZ is Asia/Shanghai and isdst=-1: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  589.     }

  590.     // test12
  591.     {
  592.         struct tm result12;
  593.         localtime_r(&now, &result12);
  594.         gettimeofday(&tv1, NULL);
  595.         for (i=0; iM; ++i)
  596.         {
  597.             struct tm result12_;
  598.             memcpy(&result12_, &result12, sizeof(result12_));
  599.             mktime(&result12_);
  600.         }
  601.         gettimeofday(&tv2, NULL);
  602.         printf("TZ is Asia/Shanghai and isdst undefined: %ums\n", (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000);
  603.     }
  604. }


上一篇:PostgreSQL 11 1万亿 tpcb 性能测试 on 阿里云ECS + ESSD + zfs/lvm2条带 + block_size=32K


下一篇:外网访问内网Redis数据库