不同容器(GCC7.1与GCC4.8.5)运行相同代码导致效率巨大差别的案件追踪(第二篇)

70 篇文章 0 订阅
37 篇文章 0 订阅

localtime函数

最权威的使用手册不是百度,而是man,在man里面提到与与时区相关。再通过谷歌找到一个前人对localtime进行调优的博客How setting the TZ environment variable avoids thousands of system calls,详细信息可以参考里面的内容描述,这里不赘述。

原因解释

按照前人得出来的结论,localtime里面,如果系统里面没有指定TZ环境变量,就会默认去读取系统中的/etc/localtime文件作为时区文件。而读文件则是磁盘IO操作,自然非常慢。因为,在GCC7.1的容器里面,我指定一下这个环境变量,再次做一下测试来验证,用实践来检查猜想。具体问题背景参考上一篇不同容器(GCC7.1与GCC4.8.5)运行相同代码导致效率具大差别的案件追踪(第一篇)

验证

在这里插入图片描述
如上图所示:两个容器的执行效率产生的巨大差异,就在这里。很明显的看出来,对可执行文件增加了TZ环境变量的设置之后,./test_log耗时从7.4S降到了4.2S。问题得到解决。

彻底挖出真相(WHY?)

具体localtime里面的逻辑是如何处理的?想要彻底搞明白,还需要真正回归到细节之中。找到容器中,对应的glibc的版本,到网络上找到对应的glibc里面的源代码,从里面找到问题的根源,为什么设置了环境变量TZ就会变快?对问题的把握,应该深入到精髓,这才是体现技术水准的时候。一切回到细节之中,找到glibc源码,打开它,一切疑问,它都能给你答案!

glibc中localtime实现细节

1、localtime.c文件中定义了localtime函数,定义如下:
在这里插入图片描述

2、tzset.c文件中的__tz_convert函数中
在这里插入图片描述

3、翻开tzset_internal函数
在这里插入图片描述

关键点来了:
1、字符串tz,这个是通过环境变量设置,如果没有设置,那每次tz进来都是空。
2、431行处,每次tz与old_tz的比较,都是不相等。old_tz在这个函数跑过一次之后,会被赋予一个默认值TZDEFAULT
3、如果tz未被设置,则每次函数都会执行__tzfile_read,去读取一个磁盘文件进行解析。
4、如果环境变量TZ被设置了,那第二次进程函数的时候,会在431行进行判断,tz值与old_tz会相等,则直接从433处返回了。
因此,TZ环境变量设置之后,只会进行一次读取磁盘文件,后续全部不会读取。因为设置TZ环境变量为/etc/localtime,localtime函数多次执行的时候,效率更高!
回头到B容器中,查找环境变量,果然!区别不在编绎器,而在于B容器多设置了一个TZ环境变量!真相终于大白!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值