这两天在验证问题的时候, 突然发现一个问题System.out.println( ) 会影响测试的准确性,
因为System.out.println( ) 本来性能就很差!!!!!!
所以特意做了个性能测试.
测试代码很简单,我就在两个代码之间增加了一行System.out.println(). 然后测试对性能的影响.
package com.system;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import org.openjdk.jmh.runner.options.Options;
import java.util.*;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime) // 测试完成时间
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 2, time = 1, timeUnit = TimeUnit.SECONDS) // 预热 2 轮,每次 1s
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) // 测试 5 轮,每次 1s
@Fork(2) // fork 2 个线程
@State(Scope.Thread) // 每个测试线程一个实例
public class SystemTest {
public static void main(String[] args) throws RunnerException {
// 启动基准测试
Options opt = new OptionsBuilder()
.include(SystemTest.class.getSimpleName()) // 要导入的测试类
// .output("/a/jmh-map.log") // 输出测试结果的文件
.build();
new Runner(opt).run(); // 执行测试
}
@Benchmark
public void nullFor() {
for (int i = 0 ; i < 100 ; i++){
String x = String.valueOf(i) ;
}
}
@Benchmark
public void OutFor() {
for (int i = 0 ; i < 100 ; i++){
System.out.println(i);
}
}
}
测试结果:
Benchmark Mode Cnt Score Error Units
SystemTest.OutFor avgt 10 1894854.560 ± 1519929.208 ns/op
SystemTest.nullFor avgt 10 1692.085 ± 200.099 ns/op
里面大量用到了 synchronized 关键字, 所以这个是同步执行的,
当有大量的并发或者使用的时候, synchronized 会造成锁升级. 当锁膨胀为重量级锁的时候,对系统性能的影响是灾难性的!!!!!!
/**
* Prints an integer and then terminate the line. This method behaves as
* though it invokes {@link #print(int)}
and then
* {@link #println()}
.
*
* @param x The int
to be printed.
*/
public void println(int x) {
synchronized (this) {
print(x);
newLine();
}
}
private void write(String s) {
try {
synchronized (this) {
ensureOpen();
textOut.write(s);
textOut.flushBuffer();
charOut.flushBuffer();
if (autoFlush && (s.indexOf('\n') >= 0))
out.flush();
}
}
catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
}
catch (IOException x) {
trouble = true;
}
}
private void newLine() {
try {
synchronized (this) {
ensureOpen();
textOut.newLine();
textOut.flushBuffer();
charOut.flushBuffer();
if (autoFlush)
out.flush();
}
}
catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
}
catch (IOException x) {
trouble = true;
}
}