鉴于我不知道在部署时我的代码将运行什么类型的系统,如何编写使用系统潜力作为衡量标准的性能基准测试。
我的意思是,如果一个系统能够每秒运行1000次代码,我希望测试能够确保尽可能接近1000。如果它只能做500,那就是我想比较它的速度。
如果它有助于使答案更具体,我正在使用JUnit4。
谢谢。
答案 0 :(得分:6)
出于几个原因,我不会将单元测试用于性能测试。
首先,单元测试不应该与周围的系统/代码有依赖关系。性能测试在很大程度上取决于硬件/操作系统,因此很难获得可在开发人员工作站,构建服务器等上使用的统一措施。
其次,单元测试应该执行得非常快。当你进行性能测试时,你通常希望拥有相当大的数据集并重复运行次数,以便平均数量/消除开销等等。这些都违背了快速测试的想法。
答案 1 :(得分:5)
测试意味着您有通过/未通过阈值。对于性能测试,这意味着太慢,你失败,足够快,你通过。如果你失败了,你就开始做返工了。
如果你不能失败,那么你就是基准测试,而不是实际测试。
当你谈到“系统能够运行”时,你必须定义“有能力”。您可以使用任何大量的硬件性能基准测试。油石,Dhrystone等很受欢迎。或者,您可能拥有数据库密集型应用程序,那么您可能需要查看TPC基准测试。或者,您可能拥有网络密集型应用程序并希望使用netperf。或者是一个GUI密集型应用程序,并希望使用某种图形基准测试。
其中任何一种都可以为您提供某种“能力”测量。选择一个或多个。他们都很好。同样值得商榷。同样偏向于你的竞争对手,远离你。
运行基准测试后,您可以运行软件并查看系统实际执行的操作。
您可以 - 如果您收集到足够的数据 - 在某些基准数字和您的性能数字之间建立一些相关性。您将看到基于工作负载,硬件配置,操作系统版本,虚拟机,数据库服务器等的各种变化。
如果有足够数据来自足够不同配置的盒子,您最终将能够开发一个性能模型,说“给定这个硬件,软件,调整参数和配置,我希望我的软件每秒做[X]次事务“。这是“有能力”的坚实定义。
拥有该模型后,您可以将软件与功能编号进行比较。在你有一个非常完整的模型之前,你真的不知道哪个系统甚至能够每秒运行1000次代码。
答案 2 :(得分:2)
我同意Brian他说单元测试不适合进行性能测试。但是,我将一个简短的示例放在一起,可用作集成测试,以便在不同的系统配置/环境中运行。
请注意,这只是为了了解可以在此处执行的操作。但是,并没有提供足够精确的结果来支持任何关于系统性能的官方声明。
import static org.junit.Assert.*;
import org.junit.Test;
package com.stackoverflow.samples.tests {
@Test
public void doStuffRuns500TimesPerSecond() {
long maximumRunningTime = 1000;
long currentRunningTime = 0;
int iterations = 0;
do {
long startTime = System.getTimeMillis();
// do stuff
currentRunningTime += System.getTimeMillis() - startTime;
iterations++;
}
while (currentRunningTime <= maximumRunningTime);
assertEquals(500, iterations);
}
}
答案 3 :(得分:0)
我对测试代码进行了一些时间测量,这些代码的目的地是实时系统,其中一个花费太长时间计算的正确答案是失败的。
我所做的就是绘制测试占用最近构建的delta cpu时间。注意,CPU时间不是实时的。实际价值并不重要 - 重要的是它改变了多少。
如果我对一个显着改变了测试运行时间的算法进行了更改,我可以轻松地放大导致它的特定变更集。我真正关心的是这些兴趣点 - 不一定是绝对值。在实时系统中经常存在许多权衡,并且这些权衡不能总是作为简单的比较表示给测试框架。
首先考虑绝对时间并将它们标准化似乎是合理的,但实际上系统和目标系统之间的转换将是非线性的 - 例如缓存压力,交换使用率,目标系统上的磁盘速度等可能导致测试在不同阈值下爆炸的时间作为您的系统。
如果您绝对需要在这方面准确的测试,请复制目标系统并将其用作测试从站,但是在您期望的类似环境中。
在我的情况下,它可能实际上是将固件下载到DSP,远程进行电源循环,从串口读取响应或看不到响应,因为它崩溃了!
- jeffk ++