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

简介: 点击(此处)折叠或打开 // 测试mktime和localtime_r性能及优化方法 // // 编译方法:g++ -g -o x x.cpp或g++ -O2 -o x x.cpp,两种编译方式性能基本相同。

点击(此处)折叠或打开

  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. }


相关文章
|
10天前
|
数据采集 数据可视化 测试技术
C#生成Selenium测试报告:实用方法与技巧
在C#中使用Selenium进行自动化测试时,结合代理IP和ExtentReports能增强测试安全性和报告质量。安装必备工具如Selenium WebDriver、NUnit和ExtentReports。在测试设置中,配置代理(如亿牛云爬虫代理)以隐藏IP,通过ChromeOptions定制UserAgent,并添加Cookie。测试代码示例展示了如何打开网页、执行搜索并生成详细的测试报告。使用ExtentReports可创建可视化测试结果,便于团队分析。
C#生成Selenium测试报告:实用方法与技巧
|
9天前
|
监控 测试技术 UED
软件测试中的性能瓶颈定位与优化策略
在软件开发的生命周期中,性能测试是确保产品质量的关键步骤之一。本文深入探讨了性能测试的重要性,并提出了一套系统的性能瓶颈定位与优化策略。通过分析现代软件系统中常见的性能问题,结合最新的研究成果和行业最佳实践,文章详细介绍了如何运用科学严谨的方法来识别和解决性能瓶颈。此外,本文还强调了逻辑严密的问题分析框架和数据驱动的决策过程对于提升软件性能的重要性。
|
6天前
|
敏捷开发 测试技术 持续交付
软件测试中的探索性测试方法
【6月更文挑战第30天】本文旨在深入探讨探索性测试(ET)方法在软件测试领域的应用及其带来的变革。通过分析ET的核心原则、实施过程和面临的挑战,文章揭示了ET如何提高测试效率,增强问题发现能力,并促进测试人员与开发人员之间的协作。同时,讨论了ET在敏捷开发环境中的适用性,以及它如何帮助企业构建更加灵活和响应迅速的测试策略。
|
3天前
|
监控 Java 数据挖掘
通过A/B测试优化返利App的功能设计
通过A/B测试优化返利App的功能设计
java.lang.NullPointerExceptionMybatisPlus出现,测试,java.lang.NullPointe,空指针异常,public方法少写了一个字段,没加注解
java.lang.NullPointerExceptionMybatisPlus出现,测试,java.lang.NullPointe,空指针异常,public方法少写了一个字段,没加注解
|
9天前
|
人工智能 安全 测试技术
现代软件测试方法及其在质量保证中的应用
在当今快节奏的软件开发环境中,软件测试作为确保产品质量的关键环节变得越发重要。本文探讨了现代软件测试方法的发展趋势及其在提升质量保证方面的应用。通过分析各种测试方法的优势和适用场景,可以帮助开发团队更有效地管理和提高软件产品的质量,以满足不断增长的用户需求。
|
17天前
|
SQL 安全 Java
探索软件测试的多维策略:从单元到集成,再到性能与安全
在软件开发过程中,测试是确保产品质量和用户满意度的关键步骤。本文将深入探讨软件测试的多维策略,包括单元测试、集成测试、性能测试和安全测试。我们将分析每种测试方法的优势和局限性,并讨论如何将这些策略整合到一个全面的测试计划中,以提高软件的可靠性和安全性。文章还将提供实用的例子和最佳实践,帮助读者更好地理解和应用这些测试技术。
|
16天前
|
芯片
LDO的原理及测试方法
LM317是一种可调稳压器,核心是Bandgap Reference,用于提供1.25到37V的输出电压和1.5A的电流。了解其内部结构有助于测试和电路设计,例如理解温度系数对稳定性的影响,以及参数如IADJ(通常为50uA)的设计。测试时关注输出电压的线性和负载调整率,同时注意输入电流与输出电流的关系。LM317的测试还包括参考电压、滤波器性能、纹波抑制比等,确保电路的稳定性和效率。在多站点测试中,还需确保辅助电路的一致性和校准。
23 4
测试时,请求方法一定要写对,写错照样出问题,Method Not Allowed 删除接口写错,注意Controller层中UserMapper中的写法,视频往后看看就能看到解决问题的方法了
测试时,请求方法一定要写对,写错照样出问题,Method Not Allowed 删除接口写错,注意Controller层中UserMapper中的写法,视频往后看看就能看到解决问题的方法了
|
4天前
|
jenkins 数据管理 测试技术
在LabVIEW开发生命周期中提高代码质量的自动化测试方法
在LabVIEW开发生命周期中提高代码质量的自动化测试方法