JHM 测试 HashMap 性能优化
1.
2.pom.xml
<dependencies> <dependency> <groupId>org.openjdk.jmh</groupId> <artifactId>jmh-core</artifactId> <version>${jmh.version}</version> </dependency> <dependency> <groupId>org.openjdk.jmh</groupId> <artifactId>jmh-generator-annprocess</artifactId> <version>${jmh.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.5.2</version> <scope>test</scope> </dependency> </dependencies> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- JMH version to use with this project. --> <jmh.version>1.21</jmh.version> <!-- Java source/target to use for compilation. --> <javac.target>1.8</javac.target> <!-- Name of the benchmark Uber-JAR to generate. --> <uberjar.name>benchmarks</uberjar.name> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <compilerVersion>${javac.target}</compilerVersion> <source>${javac.target}</source> <target>${javac.target}</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.2</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <finalName>${uberjar.name}</finalName> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>org.openjdk.jmh.Main</mainClass> </transformer> </transformers> <filters> <filter> <!-- Shading signed JARs will fail without this. http://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a-jar --> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> </configuration> </execution> </executions> </plugin> </plugins> <pluginManagement> <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>2.5</version> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.8.1</version> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.5.1</version> </plugin> <plugin> <artifactId>maven-jar-plugin</artifactId> <version>2.4</version> </plugin> <plugin> <artifactId>maven-javadoc-plugin</artifactId> <version>2.9.1</version> </plugin> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>2.6</version> </plugin> <plugin> <artifactId>maven-site-plugin</artifactId> <version>3.3</version> </plugin> <plugin> <artifactId>maven-source-plugin</artifactId> <version>2.2.1</version> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.17</version> </plugin> </plugins> </pluginManagement> </build>
3.
import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; 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; @BenchmarkMode(Mode.AverageTime) // 测试完成时间 @OutputTimeUnit(TimeUnit.NANOSECONDS) @Warmup(iterations = 1, time = 1, timeUnit = TimeUnit.SECONDS) // 预热 1 轮,每次 1s @Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS) // 测试 5 轮,每次 3s @Fork(1) // fork 1 个线程 @State(Scope.Benchmark) @Threads(100) public class HashMapTest { @Benchmark public void noSizeTest(Blackhole blackhole) { Map map = new HashMap(); for (int i = 0; i < 1024; i++) { map.put(i, i); } // 为了避免 JIT 忽略未被使用的结果 blackhole.consume(map); } @Benchmark public void setSizeTest(Blackhole blackhole) { Map map = new HashMap(1367); for (int i = 0; i < 1024; i++) { map.put(i, i); } // 为了避免 JIT 忽略未被使用的结果 blackhole.consume(map); } public static void main(String[] args) throws RunnerException { final Options opt = new OptionsBuilder() .include(HashMapTest.class.getSimpleName()) // .forks(1) .build(); new Runner(opt).run(); } }
4.
测试前后结果是对HashMap 集合初始值指定大小 的测试结果比较:差异1.07倍。建议对集合进行初始化大小 。