- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章性能优化系列:每个程序员都应该知道的数字由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
交流群里最常听到的一句话就是:我项目太垃圾了,面试怎么办。说实话,我听了也感同身受,因为我也是这么走过来的。而且,几乎大部分人都会经历这个过程。所以,不多说了,安排.
之所以挑性能优化这个方向,主要有几个原因:
1)性能优化是我很感兴趣的一个方向,同时在过去几年,我在这个方向上积累了一些经验,可以说,我之前的面试,项目上几乎是靠性能优化一招走遍天下。因此,我觉得可以拿出来和大家分享一下.
2)性能优化非常通用,几乎对于所有线上项目都可以适用,大家掌握了之后,立马可以到项目中实践起来。我想,应该不存在不需要性能优化的项目,除非你的项目只有“Hello world”.
3)性能优化大部分内容非常简单,几乎没有门槛,经验较浅的同学也很容易上手,同时性能优化也适用二八原则:掌握20%的内容,足以解决80%的问题.
4)性能优化很容易拿到结果,稍微有经验点的同学应该知道,做需求最怕拿不到结果,性能优化就不一样了,都是很直白的数字。1小时的任务,我优化成5分钟,性能提升就是十来倍,简单粗暴.
不多说了,开怼.
文章的标题来源于 Jeff Dean 在谷歌的内部一次分布式系统的演讲,英文标题为:Numbers Everyone Should Know.
这些数字与我们后续做性能优化息息相关,因此我将这部分内容放在第一篇,帮助大家建立基本的性能概念.
先来看Jeff Dean所说的数字是哪些:
注:1μs = 1000ns、1ms = 1000μs 。
操作 。 |
耗时/延迟 。 |
耗时*10亿 |
一级缓存读取(L1) 。 |
0.5ns 。 |
0.5s |
分支错误预测 。 |
5ns 。 |
5s |
二级缓存读取(L2) 。 |
7ns 。 |
7s |
互斥锁的加锁解锁 。 |
25ns 。 |
25s |
内存寻址 。 |
100ns 。 |
100s |
Zippy压缩1KB数据 。 |
3000ns(3μs) | 50min |
在1Gbps网络上发送1KB数据 。 |
10,000ns(10μs) 。 |
2.8h |
从SSD(1GB/s)随机读取4KB数据 。 |
150,000ns(150μs) | 1.7days |
从内存顺序读取1MB数据 。 |
250,000ns(250μs) 。 |
2.9days |
数据包在同数据中心一个往返 | 500,000ns(500μs) | 5.8days |
从SSD(1GB/s)顺序读取1MB数据 。 |
1,000,000ns(1ms) | 11.6days |
磁盘寻道 。 |
10,000,000ns(10ms) 。 |
3.8months |
从磁盘顺序读取1MB数据 。 |
20,000,000ns(20ms) 。 |
7.9months |
数据包从美国到荷兰一个往返 。 |
150,000,000ns(150ms) 。 |
4.75years |
表格第三列将耗时数据提升10亿倍,换算成大家更容易看的单位.
这份数据的最初来源为Peter Norvig 的文章:Teach Yourself Programming in Ten Years,地址:http://norvig.com/21-days.html.
伯克利的Colin Scott根据这份数据,通过一定的算法,制作了一个可以根据时间的推移而变化的网站,地址为:https://colin-scott.github.io/personal_website/research/interactive_latency.html,源码中注释有详细解释计算逻辑,例如网络带宽是按每2年增加1倍,DRAM带宽按每3年增加一倍.
根据 Colin Scott 的图表来看,到2021年,网络带宽、内存、SSD、磁盘,都有数量级的提升,而 CPU 相关的一二级缓存变化不大,有兴趣的可以自己点进去看一看.
首先,这些数据肯定不是完全准确的,受限于众多环境因素的影响,其实很难有所谓的准确数字.
我们看这些数据更多是了解每个操作的耗时量级,各个操作之间的数量级比率,从而对于我们工作中接触到的一些相关知识有初步的概念.
而我将这个数据放在性能优化系列文章的开篇,主要想先传达给各位同学几个概念:
CPU执行大部分简单指令只需要1个时钟周期,我用个人电脑测试时,CPU可以睿频到4.40GHz(见第2点的测试图),也就是说此时执行一个简单指令需要的时间大约是1/4.4ns,也就是0.23ns(纳秒).
这是什么概念了,举个简单的例子,即使是真空中传播的光,在0.23ns内也只能走不到7厘米.
CPU和内存之间的瓶颈通常称为冯·诺伊曼瓶颈。具体差别有多大了,我用自己的电脑做了个简单的测试.
我电脑是今年刚买的,硬件应该都还比较新,但是配置比较普通,仅供参考.
CPU配置是 11th Gen Intel Core i5-11400F@2.60GHz,睿频4.40GHz,测试结果看也确实跑到了4.40GHz了,内存配置是DDR4 3200MHz.
测试结果如下图所示:
从上图看,内存的读取速度为41GB/s,感觉还是挺快的,但是L1 Cache为3TB/s,一比较,相差还是很大.
如果CPU按4.40GHz来算,执行一个简单指令需要的时间大约是0.23ns(纳秒),而内存的延迟是88.7ns,相当于CPU去内存里取一个字节,需要等待386个周期,可以看出,内存相较于CPU来说,确实太慢了.
这也是为什么引入了L1、L2、L3缓存的原因,不过这边我们不深入去研究这些东西,只是对CPU和内存的性能差距有个大概概念.
这个大家估计大家都知道,具体有多慢了,我这边在用自己的电脑做了个简单的测试.
我电脑刚好有两块硬盘,一块256GB的SSD(固态硬盘),一块1T的HDD(机械硬盘).
SSD测试结果如下图所示:
忽略队列(Q)和线程(T)的影响,顺序读(SEQ)的性能为1535.67MB/s,随机读(RND)的性能为49.61MB/s.
对比下上面内存的性能41GB/s,尽管是SSD,性能还是存在数量级的差距,另一个就是随机读的性能相比顺序读也是存在数量级的差距.
HDD测试结果如下图所示:
忽略队列(Q)和线程(T)的影响,顺序读(SEQ)的性能为183.49MB/s,随机读(RND)的性能为0.6MB/s.
对比下上面SSD的性能:顺序读1535.67比183.49,存在一个数量级的差距,随机读49.61比0.6,存在两个数量级的差距.
而HDD顺序读和随机读的性能差距相比SSD就比较严重了,大概有300倍。简直惨不忍睹,不过相信现在的服务器应该基本都是SSD了。如果发现自己公司服务器的磁盘还是HDD,那就赶紧溜吧.
这个在上面的测试也看出来了,都是数量级上的差距,特别是在以前的HDD上。有不少技术就是利用了顺序I/O性能好的特点来提升性能,典型的有:kafka顺序写消息、Leveldb和RocksDB底层使用的LSM-Tree等.
在开始的表格中可以看到,在同数据中心一个往返,需要0.5ms.
如果是跨城市就更久了,这个相信也不难理解,毕竟信号要顺着网线爬,距离越远,当然所需时间就越久了.
下图是上海到一些城市进行PING操作所需的时间,可以看到张家口已经需要30ms左右了,这也差不多就是北上的延迟.
这也是为什么我们在服务器的路由策略上通常会优先使用同机房优先、同中心优先的策略.
这让我想到我之前碰到的一个问题,当时是一个新服务在测试,数据库基本没数据,测试场景也是很简单的增删改查,但是接口的性能就是很差,动不动就上百毫秒.
仔细看了调用链后,发现每次DB操作都需要30ms左右,看了下机房分布后,发现是应用服务器和数据库服务器跨城市了,一个在北京一个在上海,导致会有固定30ms左右的延迟。将两者换到同机房后,基本就是1ms了.
本文着重介绍了业务开发在做性能优化需要掌握的一些核心概念,之所以放在最先介绍,是因为在我做性能优化的过程中,发现绝大多数性能问题都是由于网络I/O和磁盘I/O引起的。对这些概念心中有数后,有利于我们更快的定位出性能瓶颈,从而更快的解决问题.
原文链接:https://mp.weixin.qq.com/s?__biz=MzI5NjY4MDA1NQ==&mid=2247486018&idx=1&sn=8dc206677d39a02d3f1bf1fb9a662c0d&utm_source=tuicool&utm_medium=referral 。
最后此篇关于性能优化系列:每个程序员都应该知道的数字的文章就讲到这里了,如果你想了解更多关于性能优化系列:每个程序员都应该知道的数字的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
在这段令人惊叹的视频 ( https://www.youtube.com/watch?v=udix3GZouik ) 中,Alex Blom 谈到了 Ember 在移动世界中的“黑客攻击”。 在 22
我们希望通过我们的应用收集使用情况统计信息。因此,我们希望在服务器端的某个地方跟踪用户操作。 就性能而言,哪个选项更合适: 在 App Engine 请求日志中跟踪用户操作。即为每个用户操作写入一个日
在针对对象集合的 LINQ 查询的幕后究竟发生了什么?它只是语法糖还是发生了其他事情使其更有效的查询? 最佳答案 您是指查询表达式,还是查询在幕后的作用? 查询表达式首先扩展为“普通”C#。例如: v
我正在构建一个简单的照片库应用程序,它在列表框中显示图像。 xaml 是:
对于基于 Web 的企业应用程序,使用“静态 Hashmap 存储对象” 和 apache java 缓存系统有何优缺点?哪一个最有利于性能并减少堆内存问题 例如: Map store=Applica
我想知道在性能方面存储类变量的最佳方式是什么。我的意思是,由于 Children() 函数,存储一个 div id 比查找所有其他类名更好。还是把类名写在变量里比较好? 例如这样: var $inne
我已经阅读了所有这些关于 cassandra 有多快的文章,例如单行读取可能需要大约 5 毫秒。 到目前为止,我不太关心我的网站速度,但是随着网站变得越来越大,一些页面开始需要相当多的查询,例如一个页
最近,我在缓存到内存缓存之前的查询一直需要很长时间才能处理!在这个例子中,它花费了 10 秒。在这种情况下,我要做的就是获得 10 个最近的点击。 我感觉它加载了所有 125,592 行然后只返回 1
我找了几篇文章(包括SA中的一些问题),试图找到基本操作的成本。 但是,我尝试制作自己的小程序,以便自己进行测试。在尝试测试加法和减法时,我遇到了一些问题,我用简单的代码向您展示了这一点
这个问题在这里已经有了答案: Will Java app slow down by presence of -Xdebug or only when stepping through code? (
我记得很久以前读过 with() 对 JavaScript 有一些严重的性能影响,因为它可能对范围堆栈进行非确定性更改。我很难找到最近对此的讨论。这仍然是真的吗? 最佳答案 与其说 with 对性能有
我们有一个数据仓库,其中包含非规范化表,行数从 50 万行到 6 多万行不等。我正在开发一个报告解决方案,因此出于性能原因我们正在使用数据库分页。我们的报告有搜索条件,并且我们已经创建了必要的索引,但
我有一条有效的 SQL 语句,但需要很长时间才能处理 我有一个 a_log 表和一个 people 表。我需要在 people 表中找到给定人员的每个 ID 的最后一个事件和关联的用户。 SELECT
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
通常当我建立一个站点时,我将所有的 CSS 放在一个文件中,并且一次性定义与一组元素相关的所有属性。像这样: #myElement { color: #fff; background-
两者之间是否存在任何性能差异: p { margin:0px; padding:0px; } 并省略最后的分号: p { margin:0px; padding:0px } 提前致谢!
我的应用程序 (PHP) 需要执行大量高精度数学运算(甚至可能出现一共100个数字) 通过这个论坛的最后几篇帖子,我发现我必须使用任何高精度库,如 BC Math 或 GMP,因为 float 类型不
我一直在使用 javamail 从 IMAP 服务器(目前是 GMail)检索邮件。 Javamail 非常快速地从服务器检索特定文件夹中的消息列表(仅 id),但是当我实际获取消息(仅包含甚至不包含
我非常渴望开发我的第一个 Ruby 应用程序,因为我的公司终于在内部批准了它的使用。 在我读到的关于 Ruby v1.8 之前的所有内容中,从来没有任何关于性能的正面评价,但我没有发现关于 1.9 版
我是 Redis 的新手,我有一个包含数百万个成员(member) ID、电子邮件和用户名的数据集,并且正在考虑将它们存储在例如列表结构中。我认为 list 和 sorted set 可能最适合我的情
我是一名优秀的程序员,十分优秀!