localtime() 比 gmtime() 多花 24 倍 Linux 上的性能问题

2024-01-06

由于项目的性能问题,我制作了以下测试程序(甚至使用不同的变量进行健全性检查):

int main()
{

struct tm *timeinfo;
time_t rawtime;
clock_t begin, end, begin1, end1,begin2,end2;
double time_spent;

begin = clock();

for (int i = 0; i < 1000000; i++){
    time ( &rawtime );
    timeinfo = localtime(&rawtime);
}

end = clock();
time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
printf("Time elapsed using localtime()      : %fs\n", time_spent);    
//--------------------------------

begin1 = clock();

for (int i = 0; i < 1000000; i++){
    time ( &rawtime );
    timeinfo = gmtime(&rawtime);
}

end1 = clock();
time_spent = (double)(end1 - begin1) / CLOCKS_PER_SEC;
printf("Time elapsed using gmtime()         : %fs\n", time_spent);           
//--------------------------------

begin2 = clock();

for (int i = 0; i < 1000000; i++){
    time ( &rawtime );
    localtime_r( &rawtime, timeinfo);
}

end2 = clock();
time_spent = (double)(end2 - begin2) / CLOCKS_PER_SEC;
printf("Time elapsed using localtime_r()    : %fs\n", time_spent);


return 0;
}

我得到的结果很奇怪,localtime 花费了大约 24 倍的时间,localtime_r() 函数似乎比 localtime() 花费的时间少,但仍然比 gmtime() 多得多:

Time elapsed using localtime()      : 0.958033s
Time elapsed using gmtime()         : 0.038769s
Time elapsed using localtime_r()    : 0.860276s

我用 gcc 5 和 4.x 版本编译了它,我使用了 linux Mint(更新到今天)和 CentOS5。并且在不同的物理机上进行了测试,性能差异是相似的。

为什么会有如此(巨大的)性能差异?


如果您在下面运行此代码perf record然后做perf report你会注意到localtime calls getenv("TZ")在每次迭代中。然而gmtime才不是。

查看源代码glibc确认调用图:

gmtime
    __tz_convert(, 0, )
       tzset_internal(0, 1)
mktime
    __tz_convert(, 1, )
       tzset_internal(1, 1)
           getenv("TZ")

See glibc的源代码localtime https://sourceware.org/git/?p=glibc.git;a=blob;f=time/localtime.c;h=07dd67ca71be9e2447389eee8aa28af601dc286e;hb=HEAD, gmtime https://sourceware.org/git/?p=glibc.git;a=blob;f=time/gmtime.c;h=049d551cdf4fe38bbbbc0285e64a72a0ba95ba5d;hb=HEAD and __tz_convert https://sourceware.org/git/?p=glibc.git;a=blob;f=time/tzset.c;h=eb420699c42a49b4763eb1303e033ca448c4a1db;hb=HEAD#l605.

perf report:

Samples: 78K of event 'cycles:u', Event count (approx.): 21051445406
  Children      Self       Samples  Command  Shared Object      Symbol                          ▒
+   99.48%     0.59%           349  test     test               [.] main                        ▒
+   99.48%     0.00%             0  test     libc-2.23.so       [.] __libc_start_main           ▒
+   99.48%     0.00%             0  test     test               [.] _start                      ▒
+   98.02%     7.07%          4208  test     libc-2.23.so       [.] __tz_convert                ◆
-   24.51%    23.87%         20812  test     libc-2.23.so       [.] getenv                      ▒
   - 23.87% _start                                                                              ▒
        __libc_start_main                                                                       ▒
        main                                                                                    ▒
        __tz_convert                                                                            ▒
        getenv                                                                                  ▒
   + 0.64% getenv                                                                               ▒
+   22.41%    12.75%          9877  test     libc-2.23.so       [.] __tzfile_compute            ▒
+   15.49%    15.49%          8025  test     libc-2.23.so       [.] __offtime                   ▒
+   12.72%     6.28%          5476  test     libc-2.23.so       [.] __tzfile_read               ▒
+    9.66%     3.54%          3086  test     libc-2.23.so       [.] __tzstring                  ▒
+    8.36%     1.40%          1221  test     libc-2.23.so       [.] __strdup                    ▒
+    7.68%     3.38%          2946  test     libc-2.23.so       [.] free                        ▒
+    5.98%     3.07%          2682  test     libc-2.23.so       [.] malloc                      ▒
+    4.96%     0.68%           611  test     libc-2.23.so       [.] __xstat64                   ▒
+    4.30%     4.30%          3750  test     libc-2.23.so       [.] _int_free                   ▒
+    4.28%     4.28%          3731  test     [kernel.kallsyms]  [k] entry_SYSCALL_64            ▒
+    4.08%     4.08%          3564  test     libc-2.23.so       [.] strlen                      ▒
+    3.64%     3.64%          3168  test     libc-2.23.so       [.] __memcmp_sse2               ▒
+    2.91%     2.91%          2561  test     libc-2.23.so       [.] _int_malloc                 ▒
+    1.25%     1.25%          1094  test     libc-2.23.so       [.] __memcpy_sse2               ▒
+    0.68%     0.68%           587  test     libc-2.23.so       [.] localtime                   ▒
     0.26%     0.26%           222  test     libc-2.23.so       [.] 0x000000000001f910          ▒
     0.18%     0.18%            37  test     test               [.] gmtime@plt                  ▒
     0.15%     0.15%           126  test     test               [.] localtime@plt               ▒
     0.11%     0.11%            23  test     libc-2.23.so       [.] gmtime                      ▒
     0.01%     0.01%             6  test     [kernel.kallsyms]  [k] __irqentry_text_start       ▒
     0.00%     0.00%             3  test     ld-2.23.so         [.] _dl_lookup_symbol_x         ▒
     0.00%     0.00%             5  test     ld-2.23.so         [.] do_lookup_x                 ▒
     0.00%     0.00%             2  test     ld-2.23.so         [.] _dl_relocate_object         ▒
     0.00%     0.00%             1  test     libc-2.23.so       [.] 0x000000000001f8e8          ▒
     0.00%     0.00%             1  test     ld-2.23.so         [.] strlen                      ▒
     0.00%     0.00%             1  test     ld-2.23.so         [.] _dl_debug_initialize        ▒
     0.00%     0.00%             1  test     ld-2.23.so         [.] _dl_start                   ▒
     0.00%     0.00%             1  test     [kernel.kallsyms]  [k] page_fault                  ▒
     0.00%     0.00%             6  test     ld-2.23.so         [.] _start     
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

localtime() 比 gmtime() 多花 24 倍 Linux 上的性能问题 的相关文章

  • 前向声明类型和“已声明为类类型的非类类型”

    我对以下代码有问题 template
  • 如何将 SOLID 原则应用到现有项目中

    我对这个问题的主观性表示歉意 但我有点卡住了 我希望之前处理过这个问题的人能够提供一些指导和建议 我有 现在已经成为 一个用 C 2 0 编写的非常大的 RESTful API 项目 并且我的一些类已经变得巨大 我的主要 API 类就是一个
  • RestSharp获取序列化输出

    我正在寻找一种方法来访问 AddBody 调用的序列化结果 我正在使用内置的 RestSharp 序列化器 例子 class Foo public string FooField void SendRecord var f new Foo
  • 什么是空终止字符串?

    它与什么不同标准 字符串 http www cplusplus com reference string string 字符串 实际上只是一个数组chars 空终止字符串是指其中包含空字符的字符串 0 标记字符串的结尾 不一定是数组的结尾
  • C++中判断unicode字符是全角还是半角

    我正在编写一个终端 控制台 应用程序 该应用程序应该包装任意 unicode 文本 终端通常使用等宽 固定宽度 字体 因此要换行文本 只需计算字符数并观察单词是否适合一行并采取相应的操作 问题是 Unicode 表中的全角字符在终端中占用了
  • 在 C# 中检查 PowerShell 执行策略的最佳方法是什么?

    当你跑步时Get ExecutionPolicy在 PowerShell 中 它得到有效的执行政策 https learn microsoft com en us powershell module microsoft powershell
  • 已发布的 .Net Core 应用程序警告安装 .Net Core,但它已安装

    我制作了一个 WPF 和控制台应用程序 供某人在我无法访问的私人服务器上使用 我使用 Visual Studio 2019 的内置 发布向导 来创建依赖于框架的单文件应用程序 当该人打开 WPF 应用程序时 他们会看到标准警告 他们单击 是
  • 如何递归取消引用指针(C++03)?

    我正在尝试在 C 中递归地取消引用指针 如果传递一个对象 那就是not一个指针 这包括智能指针 我只想返回对象本身 如果可能的话通过引用返回 我有这个代码 template
  • 模板外部链接?谁能解释一下吗?

    模板名称具有链接 3 5 非成员函数模板可以有内部链接 任何其他模板名称应具有外部链接 从具有内部链接的模板生成的实体与在其他翻译单元中生成的所有实体不同 我知道使用关键字的外部链接 extern C EX extern C templat
  • 在 C 中使用枚举而不是 #defines 作为编译时常量是否合理?

    在 C 工作了一段时间后 我将回到 C 开发领域 我已经意识到 在不必要的时候应该避免使用宏 以便让编译器在编译时为您做更多的工作 因此 对于常量值 在 C 中我将使用静态 const 变量或 C 11 枚举类来实现良好的作用域 在 C 中
  • 如何最好地以编程方式将 `__attribute__ ((unused))` 应用于这些自动生成的对象?

    In my makefile我有以下目标 它将文本 HTML 资源 编译 为unsigned char数组使用xxd i http linuxcommand org man pages xxd1 html 我将结果包装在匿名命名空间和标头保
  • Oauth2中如何同时撤销RefreshToken和使AccessToken失效

    我正在使用 Owin Oauth2 授权和资源服务器相同 开发单页面应用程序 AngularJS Net MVC Json Rest API 的身份验证流程 我选择了 Bearer Token 路由而不是传统的 cookie session
  • 比较:接口方法、虚方法、抽象方法

    它们各自的优点和缺点是什么 接口方法 虚拟方法 抽象方法 什么时候应该选择什么 做出这一决定时应牢记哪些要点 虚拟和抽象几乎是一样的 虚方法在基类中有一个实现 可以选择重写 而抽象方法则没有 并且must在子类中被覆盖 否则它们是相同的 在
  • Visual Studio 2015:v120 与 v140?

    仅供参考 Win10 x64 我今天开始尝试 Visual Studio 2015 在弄清楚如何运行 C C 部分后 我尝试加载一个大型个人项目 该项目使用非官方的glsdk http glsdk sourceforge net docs
  • 将 Lambda 表达式树与 IEnumerable 结合使用

    我一直在尝试了解有关使用 Lamba 表达式树的更多信息 因此我创建了一个简单的示例 这是代码 如果作为 C 程序粘贴到 LINQPad 中 它可以工作 void Main IEnumerable
  • WPF DataGrid / ListView 绑定到数组 mvvm

    我们假设你有 N 个整数的数组 表示行数的整数值 在模型中 该整数绑定到视图中的 ComboBox Q1 如何将数组 或数组的各个项目 绑定到 DataGrid 或 ListView 控件 以便 当您更改 ComboBox 值时 只有那么多
  • 代码中的.net Access Forms身份验证“超时”值

    我正在向我的应用程序添加注销过期警报 并希望从我的代码访问我的 web config 表单身份验证 超时 值 我有什么办法可以做到这一点吗 我认为您可以从 FormsAuthentication 静态类方法中读取它 这比直接读取 web c
  • Visual Studio 2015 - Web 项目上缺少共享项目参考选项卡

    我从 MSDN 订阅升级到 Visual Studio 2015 因为我非常兴奋地阅读有关共享项目的信息 当我们想要做的只是重用代码时 不再需要在依赖项中管理 21382 个 nuget 包 所以我构建了一个测试共享项目 其中包含一些代码
  • 了解 Lambda 表达式和委托 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我已经尝试解决这个问题很长一段时间了 阅读在线博客和文章 但到目前为止还没有成功 什么是代表 什么是 Lambda 表达式 两者的优点
  • 是否允许全局静态标识符以单个 _ 开头?

    换句话说 可能static 文件范围 全局变量恰好以一个下划线开头 而不会产生与 C 实现发生名称冲突的可能性 https www gnu org software libc manual html node Reserved Names

随机推荐