第2章 性能测量

理解应用程序性能的第一步是学会对它进行测量。

与绝大多数功能问题相比,性能问题通常很难跟踪和复现。

任何关注过性能评估的人可能都知道公允地进行性能测量并从中得到准确结论是多么困难。

因为在测量中存在误差,性能分析通常需要统计方法进行处理。

开展公允地性能实验是获得精确及有意义结果的基本步骤。设计性能测试和配置测试环境都是性能评估工作的重要组成部分。

2.1 现代系统中的噪声

动态频率调节是一个硬件特性,但是测量结果差异还有可能来自软件功能。

不幸的是,测量偏差还不只来自环境配置。Unix环境变量的大小(即存储环境变量所需要的字节数)和链接顺序(提供给链接器的目标文件顺序)能够对性能产生不可预知的影响。

在运行时有效且重复地将代码、堆栈和堆对象随机放置,可以消除由内存排布引起的测量偏差。

获得一致的测量结果需要所有基准测试都在同样的条件下进行。

消除系统的不确定性有助于进行定义明确、稳定的性能测试,需要控制基准测试中大部分变量,包括输入、环境配置等。

当估计实际程序的性能优化效果时,不建议去除系统的不确定的行为。工程师应当尝试复制被优化的目标系统的配置,在被测系统中引入人为调整会导致用户在实际使用中的结果不一致。此外,任何性能分析工作-包括采样,都应当在与实际部署最接近的系统下进行。

2.2 生产环境中的性能测量

随着虚拟化和容器等技术的日渐流行,公有云供应商也尝试最大化服务器资源的利用率。但是这种环境为性能测量带来了新的困难,因为与相邻进程共享资源会对性能测量产生不可预知的影响。

大型服务提供商通过部署遥测系统来监控用户设备的性能已经成为一种趋势。

测量开销是生产环境监控的一个重要问题。由于任何监控都会影响正在运行的服务的性能,因此应该使用尽可能轻量的性能剖析方法。

通常可以接受整体不超过1%的性能损失的检测开销,减少监控开销的办法包括限制被监控的机器数量和使用更小的监控时间间隔。

2.3 自动检测性能退化问题

软件供应商提高产品的部署频率逐渐成为一种趋势,但是软件的性能缺陷会以惊人的速度蔓延到生产环境中。

软件性能退化是指软件从一个版本演进到下一个版本时被错误地引入缺陷。解决办法如下:
        1. 安排人员看图来比较结果,不过这种办法很快就被抛弃了,因为人很容易因为注意力不集中而错过性能退化缺陷。
        2. 设定1个简单的阈值阀门。缺点在于选择合适的阈值门限是非常困难的事情,并且不能保证误报率低。阈值设定过低会导致误报一些由随机噪声引起的而不是代码变化引起的性能退化数据,阈值设定过高会导致过滤不出真正存在的性能退化问题。

无论使用何种算法来检测性能退化问题,典型的CI系统都应当能够自动进行以下动作:
        1. 配置待测试系统。
        2. 运行程序;
        3. 报告运行结果;
        4. 判断性能是否发生变化;
        5. 将结果可视化。

CI系统应当能够同时支持自动基准测试和手动基准测试,产生可复现的结果,并对发现的性能退化问题生成工单。迅速检测性能退化问题也非常重要。

2.4 手动性能测试

本地性能评估的基本建议:
        1. 多次测量基线性能;
        2. 多次测量修改后的程序的性能;
        3. 对2者进行比较;
使用统计分布图的一个优势是可以发现基准测试中的不良行为。如果数据分布是双峰的,基准测试会表现出两类不同的行为,引起双峰分布的常见原因是代码有快、有慢两条执行路径,例如访存缓存、获取锁等。解决这些问题的方法是隔离不同的功能模块并分别进行基准测试。

性能数据分布的可视化展示可以帮助我们发现某些异常,但我们不应当同它来进行加速比的计算。假设检验非常适合用来确定性能加速(减速)的表现是否具有随机性。

一旦通过假设检验方法确定2组数据存在统计上显著的差异,就可以使用算术平均或几何平均的方法来计算加速比。注意对于小样本采样,均值和几何均值会受到异常值影响。除非数据分布具有小方差,否则不应当只考虑使用均值。

如果测量值的方差与均值大小在同一个数量级,那么均值就不是具有代表性的指标。

为了准确地计算加速比,最重要的工作之一就是收集大量的样本数据。这听上去很容易,但有时并不可行,太多基准测试叠加下来的测试时间太长了。

需要收集多少样本数据才满足统计分布需要呢?这取决于对比测试的精确到要求。分布数据中样本的方差越小,需要的样本数越少。实施自适应策略,收集样本直到标准差达到特定的范围。

另一个需要特别小心的是异常值的存在。对某些类型的基准测试而言,异常值可能是重要的指标。

2.5 软件计时器和硬件计时器

系统级高分辨率计时器:通过统计自某任意时间起开始流逝的滴答数而实现。系统级计时器分辨率是ns级别,并且在所有CPU上都是一致的,它适合用来测量持续时间超过1us的事件。
时间戳计时器TSC:通过硬件寄存器实现的硬件计时器,它适合用来测量持续时间从ns到1 min之间的事件,可以用编译器的内置函数__rdtsc查询。

如果需要测量的时间很短暂,则TSC可以提供更好的准确度。相反,如果需要测量的时间长达数小时,则TSC测量毫无意义。除非真的需要时钟周期的精度,否则大部分情况下选择系统计时器通常就足够了。

2.6 微基准测试

微基准测试程序是在优化某些特定功能时跟踪优化进展的手段。对于C++而言,使用Google benchmark库,C#则是BenchmarkDotNet库,Julia则是BenchmarkTools库,Java则是Java Microbenchmark Harness。

定义一个基准测试优劣的依据是,它能否在真实条件下测试将来要使用的功能的性能。

如果基准测试使用的合成输入与实际使用的输入不同,那么基准测试可能会误导你。所以,在根据单元测试的结果总结结论时要小心。

2.7 本章小结

1. 由于测试的不稳定性,调试性能通常比调试功能更为困难。
2.确定预期目标,需要为如何衡量该目标设定有意义的定义和指标。根据关心的内容,它可能是吞吐量、延迟、每秒操作数(屋顶线模型)等。
3.再生产部署中衡量性能时,为了处理环境噪声的问题,需要使用统计方法分析结果。
4. 越来越多的大型分布式软件供应商选择直接在生产系统上剖析和监控性能,这要求只能使用轻量级的剖析技术。
5. 采用自动化性能跟踪系统有助于防止性能退化问题渗透到生产软件系统中,此类CI系统应能够运行自动化性能测试,可视化结果并标记潜在缺陷,这也是向受众展示性能结果的稳妥办法。
6. 性能数据分布之间的统计关系可以通过假设检验方法来识别和发现。
7. 系统级高分辨率计时器适合测量持续时间超过1us的事件,若需要高精度测量短事件,则可以使用时间戳计时器。
8. 微基准测试适合迅速证明一些事情,但是你应该始终在实际条件下用真实的程序验证你的想法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/41070.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ThreadLocal(超详细介绍!!)

关于ThreadLocal,可能很多同学在学习Java的并发编程部分时,都有所耳闻,但是如果要仔细问ThreadLocal是个啥,我们可能也说不清楚,所以这篇博客旨在帮助大家了解ThreadLocal到底是个啥? 1.ThreadLocal是什么&…

Android设备通过蓝牙HID技术模拟键盘实现

目录 一,背景介绍 二,技术方案 2.1 获取BluetoothHidDevice实例 2.2 注册/解除注册HID实例 2.3 Hid report description描述符生成工具 2.4 键盘映射表 2.5 通过HID发送键盘事件 三,实例 一,背景介绍 日常生活中&#xff0…

AndroidStudio中修改打包生成的apk名称

1.配置手机架构 splits {abi {enable truereset()include armeabi-v7a,arm64-v8auniversalApk false} } 2.多渠道 productFlavors {normal {applicationId "*****"manifestPlaceholders [appName: "string/app_name_normal"]}driver {applicationId &qu…

图片转换成pdf格式?这几种转换格式方法了解一下

图片转换成pdf格式?将图片转换成PDF格式的好处有很多。首先,PDF格式具有通用性,可以在几乎任何设备上查看。其次,PDF格式可以更好地保护文件,防止被篡改或者复制。此外,PDF格式还可以更好地压缩文件大小&am…

使用Kaptcha生成验证码

说明:验证码,是登录流程中必不可少的一环,一般企业级的系统,使用都是专门制作验证码、审核校验的第三方SDK(如极验)。本文介绍,使用谷歌提供的Kaptcha技术,制作一个简单的验证码。 …

sqlserver数据库导出到mysql

爱到分才显珍贵,很多人都不懂珍惜拥有,只到失去才看到,其实那最熟悉的才最珍贵的。 这里只介绍一种方式,有很多的方式。 1.使用Navicat 安装 下载 2.工具 数据传输 3.选择源和目标 然后开始 4.最好导入前备份一下库

【KVM虚拟化环境部署】

环境部署 KVM虚拟化环境 1、装系统时手动选择安装 2、CentOS 7 最小化安装 yum install qemu-kvm qemu-img libvirt -y yum install virt-install libvirt-python virt-manager python-virtinst libvirt-client -y安装好CentOS 7后,去设置里面点击处理器&#x…

4.0 Spring Boot入门

1. Spring Boot概述 Spring Boot介绍 Spring Boot是Pivotal团队在2014年推出的全新框架,主要用于简化Spring项目的开发过程,可以使用最少的配置快速创建Spring项目。 Spring Boot版本 2014年4月v1.0.0.RELEASE发布。 ​ 2.Spring Boot特性 约定优于配…

docker-compose部署可道云

文章目录 一. Mac1.1 下载源码1.2 部署1.2.1 修改密码部署(可忽略)1.2.2 直接部署 1.3 卸载1.4 访问 二. Win2.1 下载源码2.2 部署2.2.1 修改密码部署(可忽略)2.2.2 直接部署 2.3 卸载 一. Mac 1.1 下载源码 mkdir -p /Users/wanfei/docker-compose && cd /Users/wan…

mysql 数据备份和恢复

操作系统:22.04.1-Ubuntu mysql 版本:8.033 binlog 介绍 binlog 是mysql 二进制日志 binary log的简称,可以简单理解为数据的修改记录。 需要开启binlog,才会产生文件,mysql 8.0 默认开启,开启后可以在 /var/lib/mysql &#xff…

技术债 笔记

目录 1. 技术债 笔记1.1. 什么是技术债1.2. 讨论1.3. 国内技术从业者怎么看? 1. 技术债 笔记 1.1. 什么是技术债 1992 年, Ward Cunningham 在敏捷宣言中首次提出了"技术债"概念, 主要指有意或无意地做了错误的或不理想的技术决策所累积的债务。随后, 《重构》一书…

sql中union all、union、intersect、minus的区别图解,测试

相关文章 sql 的 join、left join、full join的区别图解总结,测试,注意事项 1. 结论示意图 对于intersect、minus,oracle支持,mysql不支持,可以变通(in或exists)实现 2.测试 2.1.创建表和数…

vue pc端项目el-upload上传图片时加水印

html代码&#xff1a; <a-uploadclass"avatar-uploader"list-type"picture-card":file-list"uploadFileList":custom-request"uploadDoneHandle":before-upload"beforeUpload":remove"removeHandle"v-decorat…

案例21 基于Spring Boot+Redis实现图书信息按书号存储案例

1. 案例需求 基于Spring BootRedis实现图书信息按书号存储和取出功能&#xff0c;数据存储至Redis。 2. 创建Spring Boot项目 创建Spring Boot项目&#xff0c;项目名称为springboot-redis02。 3. 选择依赖 ​ pom.xml文件内容如下所示&#xff1a; <?xml version&quo…

浏览器控制台调试代码和JavaScript控制台方法介绍

浏览器控制台调试代码和JavaScript控制台方法介绍 浏览器控制台调试代码 浏览器控制台&#xff08;Console&#xff09;是浏览器提供的一个开发工具&#xff0c;用于在浏览器中执行和调试 JavaScript 代码。它提供了一个交互式环境&#xff0c;可以输入 JavaScript 代码&#…

Qt:隐式内存共享

隐式内存共享 Many C classes in Qt use implicit data sharing to maximize resource usage and minimize copying. Implicitly shared classes are both safe and efficient when passed as arguments, because only a pointer to the data is passed around, and the data i…

C语言:每日一练(选择+编程)

目录 选择题&#xff1a; 题一&#xff1a; 题二&#xff1a; 题三&#xff1a; 题四&#xff1a; 题五&#xff1a; 编程题&#xff1a; 题一&#xff1a;打印1到最大的n位数 示例1 思路一&#xff1a; 题二&#xff1a;计算日期到天数转换 示例1 思路一&#xf…

【JVM】如何判定一个对象已死以及“标记-清除”、“标记-复制”、“标记-整理”三种垃圾收集算法

文章目录 0、如何判定一个对象的生死&#xff1f;1、上文提到的引用又是什么1、强引用&#xff1a;2、软引用&#xff1a;3、弱引用&#xff1a;4、虚引用&#xff1a; 2、垃圾收集算法1、标记-清除2、标记-复制优化&#xff1a;&#x1f447; 3、标记-整理 0、如何判定一个对象…

Java面向对象程序设计——知识、概念、定义及作用(简答)

​专栏&#xff1a;《Java面向对象程序设计》学习笔记 问题是依据考纲整理的&#xff0c;稍微做了一些补充。大部分答案由GPT生成&#xff0c;部分内容摘选自书本。 内容太多了&#xff0c;目前懒得浓缩精炼了&#xff0c;以后再说吧。 如果有大佬可以帮忙精简一些文字、补充…

R语言实现神经网络(1)

#R语言实现神经网络 library(neuralnet) library(caret) library(MASS) library(vcd) data(shuttle) str(shuttle)#因变量use; table1<-structable(windmagn~use,shuttle) mosaic(table1,shadingT) mosaic(use~errorvis,shuttle) prop.table(table(shuttle$use,shuttle$stab…