引言
其实很早就想写这篇文章,本篇文章不会涉及任何性能优化的知识,只是单纯的讨论一下什么是性能优化,以及为什么现在终端性能这么强大,仍需性能优化。
现如今动辄十核或二十核的CPU、高速内存和固态硬盘加持等等这么强大终端硬件设备,仍然需要做性能优化呢?我经常经常听见很多前端程序员说,写完代码,让设备去跑就好了,变卡那都是设备不行?或者说现在谁还去计较性能优化,几十毫秒哪有那么明显?
今天我们就这些问题客观的讨论一下,到底还有没有必要。
什么是性能
简单的说,性能可以理解为是一个由于多维度的参考指标构成的。
首当其冲的就是CPU性能,细分维度的话,一般CPU会参考我们的时钟周期、核心数量、线程数量、三级缓存的容量和调度效率。
再有就是内存,内存的指标无非就是单位时间内传输数据的带宽和吞吐量,内存其实参考的指标也很多,为了篇幅就不展开介绍了。
GPU,一般来说就是显卡,也可以叫协处理器,主要是进行一些简单的计算,辅助CPU处理一些图形渲染的工作,最大的优势就是可以并发处理数据,和CPU线性处理方式大有不同,可以更高效的处理图形信息,从而提高帧率和显示效果。
对于用户来说,在交互方面,性能好坏最直观的表现就是是否有明显的掉帧卡顿或者操作延迟。如果卡顿特别明显,或者首屏加载超过三秒钟,会导致流失90%的用户,简直是致命的。
高性终端能还需要优化吗?
好了开始今天的主题,对于这个问题,我们先举一个例子:
假设我们有一个128KB的内存,需要读取内存中所有的数据,我们假设CPU每处理1KB内存需要0.1ms,以伪代码举例:
const Memory = new Array(128);
for(let i = 0; i < Memory.length; i++) {
/** 需要 12.8ms **/
}
这种线性的循环操作对我们来说最平常不过了,也就12.8ms的时间,用大O表示法的话,可以表示为O(n),目前看起来问题并不大。那么我们换一种写法:
const Memory = new Array(128);
for(let i = 0; i < Memory.length; i++) {
for(let j = 0; j < Memory.length; j++) {
/** 需要 1638.4ms **/
}
}
这次双重循环(比如冒泡排序)结果或许会有点明显,大O表示法为O(n ^ 2)是原来的128倍,达到了1638.4ms,其实在刷新频率为60Hz的屏幕上,每一帧的时间仅为16.7ms,如果没有通过异步处理的话,已经会造成卡顿了(其实时间并不会这么长,只是假定条件)。那三层循环呢?就会达到O(n ^ 3),时间就会达到209715.2ms;
由此结果可想而知,如果我们电脑内存8GB的情况下,在用这种方式去处理,没有做一些优化的话,简直不敢想象,就算没处理1kb的时间是0.01ms的效率, 也不会有什么明显的改变吧?因为CPU发展至今,性能始终是线性增长的,可我们一段不好的代码,导致的性能问题将会是以指数形式增长的,远远超过我们目前硬件技术的发展;
总结
其实今天想说的问题很简答,性能优化无论在任何时候都是有必要的,比如前端目前新出的一些API,活着任何开源的框架和应用的迭代,都没有忘记在不断的对性能进行优化,其实优化性能的同时也是对自己技术的一个提升,希望无论是前端还是后端的小伙伴,都希望重视起来,写出一段烂可能只需要一个小时,写出一段优秀的代码可能需要十倍二十倍的时间去打磨。