Redian新闻
>
性能优化的十种手段(时间和空间)

性能优化的十种手段(时间和空间)

公众号新闻

作者(code2life)写了上中下三篇关于性能优化的文章,内容由浅入深涉及性能方方面面,并不仅仅局限于代码层面。

于是借花献佛,把作者的三篇整理合并之后分享给大家。希望你也能有所收获。

本文是中篇,讲解“时间”与“空间”互换取舍的手段,在程序运行期间,时间和空间都耗在哪里了

上篇:性能优化的十种手段(取与舍)

引言

前面我们总结了六种普适的性能优化方法,包括 索引、压缩、缓存、预取、削峰填谷、批量处理,简单讲解了每种技术手段的原理和实际应用。

在开启最后一篇前,我们先需要搞清楚:

在程序运行期间,时间和空间都耗在哪里了?

时间都去哪儿了?

人眨一次眼大约100毫秒,而现代1核CPU在一眨眼的功夫就可以执行数亿条指令。

现代的CPU已经非常厉害了,频率已经达到了GHz级别,也就是每秒数十亿个指令周期。

即使一些CPU指令需要多个时钟周期,但由于有流水线机制的存在,平均下来大约每个时钟周期能执行1条指令,比如一个3GHz频率的CPU核心,每秒大概可以执行20亿到40亿左右的指令数量。

程序运行还需要RAM,也可能用到持久化存储,网络等等。随着新的技术和工艺的出现,这些硬件也越来越厉害,比如CPU高速缓存的提升、NVMe固态硬盘相对SATA盘读写速率和延迟的飞跃等等。这些硬件具体有多强呢?

有一个非常棒的网站“Latency Numbers Every Programmer Should Know”,可以直观地查看从1990年到现在,高速缓存、内存、硬盘、网络时间开销的具体数值。

https://colin-scott.github.io/personal_website/research/interactive_latency.html

下图是2020年的截图,的确是“每个开发者应该知道的数字”。



这里有几个非常关键的数据:

  • 存取一次CPU多级高速缓存的时间大约1-10纳秒级别;

  • 存取一次主存(RAM)的时间大概在100纳秒级别;

  • 固态硬盘的一次随机读写大约在10微秒到1毫秒这个数量级;

  • 网络包在局域网传输一个来回大约是0.5毫秒。

看到不同硬件之间数量级的差距,就很容易理解性能优化的一些技术手段了。

比如一次网络传输的时间,是主存访问的5000倍,明白这点就不难理解写for循环发HTTP请求,为什么会被扣工资了。

放大到我们容易感知的时间范围,来理解5000倍的差距:如果一次主存访问是1天的话,一趟局域网数据传输就要13.7年。

如果要传输更多网络数据,每两个网络帧之间还有固定的间隔(Interpacket Gap),在间隔期间传输Idle信号,数据链路层以此来区分两个数据包,具体数值在链接Wiki中有,这里截取几个我们熟悉的网络来感受一下:

  • 百兆以太网: 0.96 µs

  • 千兆以太网:96 ns

  • 万兆以太网:9.6 ns

不过,单纯看硬件的上限意义不大,从代码到机器指令中间有许多层抽象,仅仅是在TCP连接上发一个字节的数据包,从操作系统内核到网线,涉及到的基础设施级别的软硬件不计其数。到了应用层,单次操作耗时虽然没有非常精确的数字,但经验上的范围也值得参考:

  • 用Memcached/Redis存取缓存数据:1-5 ms

  • 执行一条简单的数据库查询或更新操作:5-50ms

  • 在局域网中的TCP连接上收发一趟数据包:1-10ms;广域网中大约10-200ms,视传输距离和网络节点的设备而定

  • 从用户态切换到内核态,完成一次系统调用:100ns - 1 μs,视不同的系统调用函数和硬件水平而定,少数系统调用可能远超此范围。

空间都去哪儿了?

在计算机历史上,非易失存储技术的发展速度超过了摩尔定律。除了嵌入式设备、数据库系统等等,现在大部分场景已经不太需要优化持久化存储的空间占用了,这里主要讲的是另一个相对稀缺的存储形式 —— RAM,或者说主存/内存。

以JVM为例,在堆里面有很多我们创建的对象(Object)。

  • 每个Object都有一个包含Mark和类型指针的Header,占12个字节

  • 每个成员变量,根据数据类型的不同占不同的字节数,如果是另一个对象,其对象指针占4个字节

  • 数组会根据声明的大小,占用N倍于其类型Size的字节数

  • 成员变量之间需要对齐到4字节,每个对象之间需要对齐到8字节

如果在32G以上内存的机器上,禁用了对象指针压缩,对象指针会变成8字节,包括Header中的Klass指针,这也就不难理解为什么堆内存超过32G,JVM的性能直线下降了。

举个例子,一个有8个int类型成员的对象,需要占用48个字节(12+32+4),如果有十万个这样的Object,就需要占用4.58MB的内存了。这个数字似乎看起来不大,而实际上一个Java服务的堆内存里面,各种各样的对象占用的内存通常比这个数字多得多,大部分内存耗在char[]这类数组或集合型数据类型上。

举个例子,一个有8个int类型成员的对象,需要占用48个字节(12+32+4),如果有十万个这样的Object,就需要占用4.58MB的内存了。这个数字似乎看起来不大,而实际上一个Java服务的堆内存里面,各种各样的对象占用的内存通常比这个数字多得多,大部分内存耗在char[]这类数组或集合型数据类型上。

堆内存之外,又是另一个世界了。

从操作系统进程的角度去看,也有不少耗内存的大户,不管什么Runtime都逃不开这些空间开销:每个线程需要分配MB级别的线程栈,运行的程序和数据会缓存下来,用到的输入输出设备需要缓冲区……

代码“写出来”的内存占用,仅仅是冰山之上的部分,真正的内存占用比“写出来”的要更多,到处都存在空间利用率的问题。

比如,即使我们在Java代码中只是写了 response.getWriter().print(“OK”),给浏览器返回2字节,网络协议栈的层层封装,协议头部不断增加的额外数据,让最终返回给浏览器的字节数远超原始的2字节,像IP协议的报头部就至少有20个字节,而数据链路层的一个以太网帧头部至少有18字节。

如果传输的数据过大,各层协议还有最大传输单元MTU的限制,IPv4一个报文最大只能有64K比特,超过此值需要分拆发送并在接收端组合,更多额外的报头导致空间利用率降低(IPv6则提供了Jumbogram机制,最大单包4G比特,“浪费”就减少了)。

这部分的“浪费”有多大呢?下面的链接有个表格,传输1460个字节的载荷,经过有线到无线网络的转换,至少再添120个字节,**空间利用率<92.4%**。

https://en.wikipedia.org/wiki/Jumbo_frame

这种现象非常普遍,使用抽象层级越高的技术平台,平台提供高级能力的同时,其底层实现的“信息密度”通常越低。

像Java的Object Header就是使用JVM的代价,而更进一步使用动态类型语言,要为灵活性付出空间的代价则更大。哈希表的自动扩容,强大的反射能力等等,背后也付出了空间的代价。

再比如,二进制数据交换协议通常比纯文本协议更加节约空间。但多数厂家我们仍然用JSON、XML等纯文本协议,用信息的冗余来换取可读性。即便是二进制的数据交互格式,也会存在信息冗余,只能通过更好的协议和压缩算法,尽量去逼近压缩的极限 —— 信息熵。

小结

理解了时间和空间的消耗在哪后,还不能完全解释软件为何倾向于耗尽硬件资源。有一条定律可以解释,正是它锤爆了摩尔定律。

它就是安迪-比尔定律。

“安迪给什么,比尔拿走什么”。

安迪指的是Intel前CEO安迪·葛洛夫,比尔指的是比尔·盖茨。

这句话的意思就是:软件发展比硬件还快,总能吃得下硬件

20年前,在最强的计算机也不见得可以玩赛车游戏;

10年前,个人电脑已经可以玩画质还可以的3D赛车游戏了;

现在,自动驾驶+5G云驾驶已经快成为现实。

在这背后,是无数的硬件技术飞跃,以及吃掉了这些硬件的各类软件。

这也是我们每隔两三年都要换手机的原因:不是机器老化变卡了,是嗜血的软件在作怪。



因此,即使现代的硬件水平已经强悍到如此境地,性能优化仍然是有必要的。

软件日益复杂,抽象层级越来越高,就越需要底层基础设施被充分优化。

对于大部分开发者而言,高层代码逐步走向低代码化、可视化,“一行代码”能产生的影响也越来越大,写出低效代码则会吃掉更多的硬件资源。


作者:code2life

来源:https://code2life.top/2020/08/15/0055-performance/


相关阅读:

高性能计算技术、方案和行业全解(第二版)

InfiniBand架构和技术实战总结(第二版)

RDMA原理分析、对比和技术实现解析


​​全店铺技术资料打包(全)




转载申明:转载本号文章请注明作者来源,本号发布文章若存在版权等问题,请留言联系处理,谢谢。


推荐阅读

更多架构相关技术知识总结请参考“架构师全店铺技术资料打包”相关电子书(37本技术资料打包汇总详情可通过“阅读原文”获取)。

全店内容持续更新,现下单“架构师技术全店资料打包汇总(全)”,后续可享全店内容更新“免费”赠阅,价格仅收198元(原总价350元)。



温馨提示:

扫描二维码关注公众号,点击阅读原文链接获取架构师技术全店资料打包汇总(全)电子书资料详情


微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
这几种神级性能优化手段,你用过几个?系统性能优化的十大策略(强烈推荐,建议收藏)英国推出弹性工作制:雇员可要求灵活工作时间和地点!英美达成能源协议,有助于降低英国能源价格!活久见!华女用变声器以各种手段让“死了都要爱女友”订购送餐+拍不雅影片男人心里最 迷 人的十种女人,看看你榜上有名吗?MySQL性能优化浅析及线上案例[日签] 大多数人都把时间和精力浪费在了问题本身Nginx 一网打尽:动静分离、压缩、缓存、黑白名单、跨域、高可用、性能优化...美领馆各签证中心正常开放!北京签证中心不再查看核酸!(内附最新签证预约时间)美国总统日:就职演讲名段(1933年-2017年)年末促销:各种手提包、钱包、鞋子最高50%折扣!@ Coach智人必有笨相 好学是吾家风Diwali 2022四场免费写作直播课(今晚第二场,昨天搞错时间)系统性能优化十种手段(并行)公民子女申请父母(在美国)的十种情况,你属于哪一种?!Linux 性能优化实战-网络丢包问题分析“报复性”旅游 行前巧安排,谈永久居民的境外时间和回美证的申请古诗词中的十种情这10种神级性能优化手段,你用过几个?(中)童言无忌:你有时间和总统做浪漫的事吗,小丽脸红了……Nginx一网打尽:动静分离、压缩、缓存、黑白名单、跨域、高可用、性能优化...众议院公布特朗普纳税申报表,显示其采用多种手段逃避纳税超算行业:全球及中国市场现状如何?未来空间和竞争格局《舌尖3》里这种手工锻打的传统不粘锅,才是国货该有的样子Ceph OSD CPU 性能优化 -第 1 部分金阁粤式烧腊在美国272.放毒、陷害【十大券商一周策略】A股正进入牛市初期的上升通道!反弹时间和空间有望进一步打开这10种神级性能优化手段,你用过几个?(下)性能优化的十种手段(取与舍)这 10 种神级性能优化手段,你用过几个?胡离场起因新视频无解 揭开真相之最佳猜想美国大学常规录取阶段(RD)攻略「漫画小学生自我管理(时间+情绪+社交) (全3册)」给小学生妙趣横生的自我管理读本
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。