美文网首页
Java 线程(5)- 性能测试

Java 线程(5)- 性能测试

作者: skeeey | 来源:发表于2019-01-27 16:22 被阅读11次
Ottawa, Canada by @marcojodoin

Avoid premature optimization. First make it right, then make it fast - if it is not already fast enough

衡量性能的指标

  • 响应时间(Responsiveness),程序或服务对一个相关请求的相应时间
  • 吞吐量(Throughout),程序或服务单位时间内可以完成的工作量
  • 伸缩性(Scalability),当增加计算资源(如: CPUs, memory, storage, or I/O bandwidth)后, 可以提高多少吞吐量

Amdahl定理

Amdahl's law describes how much a program can theoretically be sped up by additional computing resources, based on the proportion of parallelizable and serial components.

Speedup\leq\frac{1}{F + \frac{(1 - F)}{N}}

  • Speedup :通过添加计算资源(如CPUs, memory),程序或应用可获得的加速速率
  • F:程序或应用中不可并行化的部分所占的比率
  • N:计算资源的数量

N 无限大时,SpeedupF 成反比, 也就是如果程序或应用中大部分是不可并行执行的,即使增加再多的计算资源, 程序的性能也不可能获得很大的提升。相反,如果程序中的任务完全可并行执行,即 F=0(现实世界中,这样的程序是不存在的, 任何一个程序中都含有一些不可并行化的部分),那么 Speedup = N,即可通过增加计算资源,来获得很大的性能提升。因此, 仔细的分析程序中不可并行化的部分(如一些隐含的不可并行的部分:从任务队列中取任务,计算结果的汇集,等)对性能提升是很重要的。

影响线程开销的因素

  • 上下文切换(Context switching),线程的上下文切换是线程状态由 blocked 变为 running 或由 running 变为 blocked 的引起的,主要来自操作系统或JVM 对进程或线程调度的开销,过度的上下文切换会导致程序性能的低下,其中 IO 操作最容易引起上下文切换,因此应尽量分离 IO 操作,一个好的经验法则是,上下文切换的时间应该在 0.5 ms 到几微秒之间
  • 内存同步(Memory synchronization),为了使内存同步,常用的方法要么串行化程序,而过度的串行化会影响程序的吞吐量,要么使用锁,而不当的加锁(不要担心正常的使用锁,JVM 对此已经优化的足够好了),可能带来锁竞争的问题,该问题不但影响程序的吞吐,同时还会影响程序的性能。影响锁竞争的因素包括:锁被请求的频率和锁被持有的时间,根据 Little 定律如果两者的乘积足够小,那么程序的性能会得到很好的提高,因此,可以改善程序的方法包括:
  1. 减小锁被持有的时间,即缩小锁的范围,快进快出,尽可能的缩小 synchronized 块的范围,尤其是在保证程序正确的情况下, 尝试把计算和阻塞(如I/O)操作移出 synchronized
  2. 减小锁被请求的频率,如对不相关的独立状态变量,用不同的锁进行守护、尝试将一个容器(如:ConcurrentHashMap)进行拆分,然后使用不同的锁对拆分后的片段进行守护, 但该技术有一定的副作用,如:很难对整个容器进行加锁,因此可能在一定程度上带来可见性的问题、避免在频繁调用的代码上加锁和避免使用排他锁(Exclusive Locks)
  • 阻塞(Blocking),主要来自对资源、锁或 I/O 的竞争

测试

The goal of testing is not so much to find errors as it is to increase confidence that the code works as expected

制定测试计划

  • What do you mean by "faster"? (预期)
  • Under what conditions will this approach actually be faster? Under light or heavy load? With large or small data sets? Can you support your answer with measurements? (条件)
  • How often are these conditions likely to arise in your situation? Can you support your answer with measurements? (测量)
  • Is this code likely to be used in other situations where the conditions may be different? (环境)
  • What hidden costs, such as increased development or maintenance risk, are you trading for this improved performance? Is this a good trade off? (隐含的代价)

测试的方法

  • 基本的单元测试(保证基本的功能正确)
  • 测试阻塞操作(设定等待时间->中断->Thread.join())
  • 构造测试程序与数据(问题集中在如何验证测试数据? 如何提高测试程序的并发性? 如何跟踪线程)
  • 测试内存泄露(可以使用 profile 工具)
  • 性能测试

避免测试中的陷阱

  1. GC,要求运行测试的时间足够长,以保证 JVM 有 GC 的发生
  2. 动态编译,同样要求运行测试的时间足够长,即 JVM 的预热,并且应该舍去第一运行的数据
  3. 关注 JVM 对代码的优化,主要集中在两个方面,一是测试程序对代码的覆盖率,另一个是避免 JVM 将一些测试基准当做 dead code 优化掉, 要求测试总在 -server 下运行
  4. 尽量的模仿实际情况

分析测试结果

  • CPU 是否被均匀的使用,如:一些 CPU 负载高,而另一些负载低,这说明大多数计算集中在某一(某些)线程(集合)中, 因此需要加强程序的并行化
  • CPU 是否被充分的使用,如:负载不够,I/O 限制,外部限制(如:数据库,web service等),锁竞争,可以使用 profiler 来分析

相关文章

  • Java 线程(5)- 性能测试

    Avoid premature optimization. First make it right, then m...

  • 接口操作

    Apache tomcat jmeter---java语言开发的,性能测试 jmeter操作步骤 1.新建线程组 ...

  • 2018-07-27

    Apache tomcat jmeter---java语言开发的,性能测试 jmeter操作步骤 1.新建线程组 ...

  • 并发模式对比:akka和goroutine

    计算密集型性能对比 通过级数计算PI的值,来比较Java线程,akka和goroutine之间的性能差异。 测试环...

  • 单元测试

    单元测试 线程 性能优化

  • 加速开发XCODE项目

    1.增加XCode执行的线程数 (未测试) 可以根据自己Mac的性能,更改线程数设置5: defaults wri...

  • 使用Jmeter测试java请求

    1、性能测试过程中,有时候开发想对JAVA代码进行性能测试,Jmeter是支持对Java请求进行性能测试,但是需要...

  • 查看源码——并发类

    java.util.current包:包含许多线程安全、测试良好、高性能的并发构建块包含3个包:Atomic(原子...

  • ABtest 性能测试

    ABtest 性能测试 ab 模拟 get 性能测试: -n 请求次数-c 请求线程数最后是路径 --...

  • 性能测试基础概念

    一、性能测试工具 二、性能测试基础 三、服务器性能诊断知识 知识点:1.进程、线程任务之间的区别2.线程的中断优先...

网友评论

      本文标题:Java 线程(5)- 性能测试

      本文链接:https://www.haomeiwen.com/subject/botnjqtx.html