有一个问题,即简单循环的性能(请参阅下面的LoopTest.performTest中的代码)变化很大,但在过程的生命周期内是一致的。
例如,当从Weblogic / Tomcat中运行时,它可能每秒平均达到35亿次迭代。重新启动,它可能每秒只能实现2000万次迭代。这将在整个过程的生命周期内保持一致。当它直接从命令行运行时,每次都运行得很快。
这是在linux,windows,Tomcat&的WebLogic。 WebLogic中的执行速度比Tomcat更频繁。
测试细则
测试代码将任何潜在的OS调用(时间)移动到测试之前和之后,具有不同的大小循环,这应该允许任何缓慢的OS调用作为随着循环大小增加而逐渐显着的性能改进而显而易见。
测试执行的迭代次数由时间(参见runTest)确定,而不是由于性能的大变化而被修复,因此比最初预期的更复杂。
public static abstract class PerformanceTest {
private final String name;
public PerformanceTest(String name) {
this.name = name;
}
/**
* Return value to ensure loops etc not optimised away.
*
* @param loopCount
* @return
*/
public abstract long performTest(final long loopCount);
public String getName() {
return name;
}
}
private static class LoopTest extends PerformanceTest {
LoopTest() {
super("Loop");
}
@Override
public long performTest(final long loopCount) {
long sum=0;
for(long i=0;i<loopCount;i++) {
sum+=i;
}
return sum;
}
}
public static List<PerformanceTest> loadTests() {
List<PerformanceTest> performanceTests = new ArrayList<PerformanceTest>();
performanceTests.add(new LoopTest());
return performanceTests;
}
public static void main(String[] argv) {
int maxDuration = 30;
if (argv.length == 1) {
maxDuration = Integer.parseInt(argv[0]);
}
List<PerformanceTest> tests = loadTests();
for(PerformanceTest test : tests) {
runTest(test, maxDuration);
}
}
public static void runTest(PerformanceTest test, int maxDuration) {
System.out.println("Processing " + test.getName());
long stopDuration = 1000 * maxDuration;
long estimatedDuration = 1;
long priorDelta = 1;
long loopCount=10;
while (estimatedDuration < stopDuration) {
long startTime = System.currentTimeMillis();
test.performTest(loopCount);
long endTime = System.currentTimeMillis();
long delta = endTime - startTime;
estimatedDuration = delta * Math.max(10, delta / Math.min(estimatedDuration, priorDelta));
if (estimatedDuration <= 0) {
estimatedDuration = 1;
}
priorDelta = delta;
if (priorDelta <= 0) {
priorDelta = 1;
}
if (delta > 0) {
double itemsPerSecond = 1000 * (double)loopCount / (double)delta;
DecimalFormat formatter;
if (itemsPerSecond < 1) {
formatter = new DecimalFormat( "#,###,###,##0.000");
} else if (itemsPerSecond < 10) {
formatter = new DecimalFormat( "#,###,###,##0.0");
} else {
formatter = new DecimalFormat( "#,###,###,##0");
}
System.out.println(" " + loopCount + " : Duration " + delta + ", Items Per-Second: " + formatter.format(itemsPerSecond));
}
loopCount*=10;
}
}