[翻译]编写高性能 .NET 代码 第一章:性能测试与工具 -- 平均值 vs 百分比

时间:2022-12-25 20:00:01

<<返回目录

平均值 vs 百分比

在考虑要性能测试的目标值时,我们需要考虑用什么统计口径。大多数人都会首选平均值,但在大多数情况下,这个正确的,但你也应该适当的考虑百分数。但你有可用性的要求,作为性能测试的目标里肯定会有用百分比作的要求。举个栗子:“数据库请求的平均延迟必须小于10ms,95%是请求必须小于100ms”
。。。(这里我省略了对“95%是请求必须小于100ms”的翻译说明,我觉得中国的程序猿应该看得懂我翻译的那句话)

1,2,2,4,5,5,8,10,10,11,11,11,15,23,24,25,50,87

举个栗子,上面有18个测试下来的值(已经过排序了的),的平均耗是17ms,但有5%的访问超过50ms。如果你刚好只看平均值,你一定会认为一切正常。但当你用了百分比作为指标,你就会知道一些偶发的GC操作会影响到你的访问质量。

百分比是高可用性的最重要指标。如果你需要更高的可靠性,就需要提出一个更高的百分数指标。通常来说99%已经很好了,但你还会可能有99.99% 99.999%,甚至更高的指标,但通常来说,决定采用这些指标数字取决于业务,而不是开发。

这里作为翻译的我,来补一些关于百分比的数据
99% 允许每年服务器挂 3.65 天(多让人尴尬的数据啊,但我相信很多公司服务器不一定达能到这个要求)
99.9% 允许每年挂 8.76 小时(1年出了一次较大的事故,基本就用完额度了)
99.99% 允许每年挂 52.6 分钟(1年只能出一次小的事故,还得是能立即解决的)
99.999% 允许每年挂 5.26 分钟(如果真的发生小于这个时间的事故,对于用户来说一般很难有感知,但是在淘宝双十一零点之后的一个小时内碰上的话 (=@__@=) )
99.9999% 允许每年挂 31 秒(写一个程序在一年的时间里只往控制台输出 hello world的同时还得祈求上帝保证机房不要断电 O(∩_∩)O!)

百分比是一个重要的指标,是因为他可以帮助你了解你的系统,即使通过平均值观察到,你的系统一切正常,但是只有90%的用户访问满足了目标,也会意味着,你还有10%的用户访问还有可以改进的空间。要解决这这部分请求问题,需要的更多是商业上的考量,因为这里会存在一个递减回报的问题,因为提升最后的1%要花的时间不是一般的多。

对于上面的例子“有95%的访问请求满足了50ms以内的需求”,但数据源来说,不符合统计学上对样本数量的要求,至少要要相同数量级的样本才行。要描述 99% 需要统计100个样本,要描述 99.9% 则至少要1000个样本,并以此类推。

再举一个作为翻译我的栗子
话说当年做的页游上线,在开服到了几百人(>500)的时候玩家会觉得比较卡,登陆服务器看了一下cpu和网络情况都不是很高(<30%),内存占也没啥问题。经过后来多方努力,发现是用户首次进入游戏时,为了数据安全,这时候初始化数据库的操作是同步的,而不是异步的。再加上dogse引擎的限定,主逻辑是跑在单线程的队列上,这就导致开服时主线程的阻塞会比较严重。每个玩家卡个200ms,同时有3个玩家进入,剩下的玩家自然会觉得卡了。

对于本书最重要的,而起是要重复说三遍的观点是:

测量,测量,测量

你要知道,如果没有准确的测量,在解决性能相关问题时,你只能按照自己的经验和感觉来判断那里有性能问题。这会存在2个问题:
首先:假设你的感觉是对的,找到了一个性能问题的地方,但你不知道当你修改了这里后,对性能提升了多少
其次:我也不可能告诉你那里经常犯错了。举个栗子(这个栗子我没看懂):在分析一个应用占用里很多非托管内存的问题,我们最初假设是认为在某处加载了一个很大的数据。随后安排开发人员做排查工作,通过禁止某些组件的加载,还调试了转储过程(dump)里堆的数据。结果让我们很吃惊,大部分内存的开销来自于组件(Assembly)加载,而不是我们之前所想的数据加载

如果没有工具做测量,那么性能优化就是没意义的。性能优化是一个连续的过程,你需要有自己的工具来对这个过程做记录。下面的章节将介绍一些常见的工具。恩大部分是免费的,有一款收费的,但是是vs专业版附带的,所以你懂的。

下一节 >> Visual Studio

[翻译]编写高性能 .NET 代码 第一章:性能测试与工具 -- 平均值 vs 百分比的更多相关文章

  1. &lbrack;翻译&rsqb;编写高性能 &period;NET 代码 第一章:工具介绍 -- Visual Studio

    <<返回目录 Visual Studio vs虽然不是全宇宙唯一的IDE,但它是.net开发人员最常用的开发工具.它自带一个性能分析工具,你可以使用它来做开发,不同的vs版本在工具上会略有 ...

  2. &lbrack;翻译&rsqb;编写高性能 &period;NET 代码 第一章:工具介绍 -- Performance Counters(性能计数器)

    <<返回目录 Performance Counters(性能计数器) 性能计数器是监视应用程序和系统性能的最简单的方法之一.它有几十个类别数百个计数器在,包括一些.net特有的计数器.要访 ...

  3. &lbrack;翻译&rsqb; 编写高性能 &period;NET 代码--第二章 GC -- 减少分配率&comma; 最重要的规则&comma;缩短对象的生命周期&comma;减少对象层次的深度&comma;减少对象之间的引用&comma;避免钉住对象(Pinning)

    减少分配率 这个几乎不用解释,减少了内存的使用量,自然就减少GC回收时的压力,同时降低了内存碎片与CPU的使用量.你可以用一些方法来达到这一目的,但它可能会与其它设计相冲突. 你需要在设计对象时仔细检 ...

  4. &lbrack;翻译&rsqb;编写高性能 &period;NET 代码 第二章:垃圾回收

    返回目录 第二章:垃圾回收 垃圾回收是你开发工作中要了解的最重要的事情.它是造成性能问题里最显著的原因,但只要你保持持续的关注(代码审查,监控数据)就可以很快修复这些问题.我这里说的"显著的 ...

  5. &lbrack;翻译&rsqb; 编写高性能 &period;NET 代码--第二章 GC -- 避免使用终结器&comma;避免大对象&comma;避免复制缓冲区

    避免使用终结器 如果没有必要,是不需要实现一个终结器(Finalizer).终结器的代码主要是让GC回收非托管资源用.它会在GC完成标记对象为可回收后,放入一个终结器队列里,在由另外一个线程执行队列里 ...

  6. &lbrack;翻译&rsqb; 编写高性能 &period;NET 代码--第二章 GC -- 将长生命周期对象和大对象池化

    将长生命周期对象和大对象池化 请记住最开始说的原则:对象要么立即回收要么一直存在.它们要么在0代被回收,要么在2代里一直存在.有些对象本质是静态的,生命周期从它们被创建开始,到程序停止才会结束.其它对 ...

  7. &lbrack;翻译&rsqb; 编写高性能 &period;NET 代码--第二章 GC -- 减少大对象堆的碎片&comma;在某些情况下强制执行完整GC&comma;按需压缩大对象堆&comma;在GC前收到消息通知&comma;使用弱引用缓存对象

    减少大对象堆的碎片 如果不能完全避免大对象堆的分配,则要尽量避免碎片化. 对于LOH不小心就会有无限增长,但LOH使用的空闲列表机制可以减轻增长的影响.利用这个空闲列表,我们可以在两块分配区域中间找到 ...

  8. &lbrack;翻译&rsqb;编写高性能 &period;NET 代码 第二章:垃圾回收 基本操作

    返回目录 基本操作 垃圾回收的算法细节还在不断完善中,性能还会有进一步的提升.下文介绍的内容在不同的.NET版本里会略有不同,但大方向是不会有变动的. 在.net进程里会管理2个类型的内存堆:托管和非 ...

  9. &lbrack;翻译&rsqb; 编写高性能 &period;NET 代码--第二章 GC -- 配置选项

    配置选项 在基于"less rope to hang yourself with"思想下,.NET 框架没有给开发提供很多太多的配置选项.但在大多数情况下,GC会跟你的硬件配置,及 ...

随机推荐

  1. PHP判断字符串中是否包含指定字符串,支持中文哦

    RT,随手写的 /** * 判断字符串中是否包含指定字符串 * @var source 源字符串 * @var target 要判断的是否包含的字符串 * @return bool */ functi ...

  2. &lbrack;codeforces 325&rsqb;B&period; Stadium and Games

    [codeforces 325]B. Stadium and Games 试题描述 Daniel is organizing a football tournament. He has come up ...

  3. ZigBee profile

        每个ZigBee设备都与一个特定模板相关联,可能是公共模板或私有模板.这些模板定义了设备的应用环境.设备类型以及用于设备间通信的簇.采用公共模板,可以确保不同供应商的设备在相同应用领域的互操作 ...

  4. BIND9源码学习笔记1---gdb调试篇

    学习bind9源码之前,首先要知道如何用gdb来调试bind.BIND9的源码我是先看代码弄懂它的架构,像什么event-drive,epoll等, 再去看它的业务流程.看业务流程的时候要追踪它的数据 ...

  5. Spring-Junit4

      Spring整合Junit4测试Service 1. 加入依赖包 使用Spring的测试框架需要加入以下依赖包: JUnit 4 (官方下载:https://github.com/KentBeck ...

  6. NYOJ 58 步数最少 【BFS】

    意甲冠军:不解释. 策略:如果: 这个问题也可以用深宽搜索搜索中使用.我曾经写过,使用深层搜索.最近的学校范围内的搜索,拿这个问题来试试你的手. 代码: #include<stdio.h> ...

  7. ionic2&plus;angularjs2

    感觉TypeScript真不错,强类型,有点类似c#的感觉,而且如果写错了编辑器都可以感知出来,于是就开始看ionic2.ionic2是基于angular2的,语法跟以前有了很大的变化.但自己写原生a ...

  8. 【mysql】字段类型和长度的解释

    int(11)最大长度是多少,MySQL中varchar最大长度是多少? int(11)最大长度是多少? 在SQL语句中int代表你要创建字段的类型,int代表整型,11代表字段的长度. 这个11代表 ...

  9. js 获取json对象的Key、value(js遍历json对象的key和value)

    <script type="text/javascript"> getJson('age'); function getJson(key){ "," ...

  10. MySql(十三):MySql架构设计——可扩展性设计之 MySQL Replication

    一.前言 MySQL Replication能够将一个 MySQL Server 的 Instance 中的数据完整的复制到另外一个 MySQL Server 的 Instance 中.虽然复制过程并 ...