nanobench - Java 8 で簡単にマイクロベンチマークをとれるフレームワーク作った
Caliper や JMH などを試してみたが、案外あれは使うのが難しかったり、インストールが難しかったり、結果がよみづらかったりする。 Perl 5 に標準添付されているベンチマークフレームワークであるところの Benchmark.pm と同じぐらい気軽な感じで使えるベンチマークフレームワークが Java 8 用にあれば便利なのではないか、と思ったので作ってみた。
https://github.com/tokuhirom/nanobench
先日つくった HTML escape に関するマイクロベンチマークを nanobench を使って書きなおしてみる。
package me.geso.microbenchmarks;
import me.geso.nanobench.Benchmark;
import org.apache.commons.lang3.StringEscapeUtils;
import org.junit.Test;
import org.springframework.web.util.HtmlUtils;
import com.google.common.html.HtmlEscapers;
public class HTMLEscapeTest {
@Test
public void testHTMLEscape() throws Exception {
final String src = "<><><><>&&&&;;;;jl2kjlnnfljflksdjfuowu-9urjnl321knl;fu3poifuokbkvnl;uigufjslfjadsipuru1o2krn;lkmfzkjhvojopijkJ:LJKU)!*)($J!KLJOIFHS)JPJ";
new Benchmark()
.add("guava", () -> {
HtmlEscapers.htmlEscaper().escape(src);
})
.add("commons", () -> {
StringEscapeUtils.escapeHtml4(src);
})
.add("String.replace",
() -> {
src.replace("&", "&").replace(">", ">")
.replace("<", "<")
.replace("'", "'")
.replaceAll("\"", """);
}).add("Spring", () -> {
HtmlUtils.htmlEscape(src);
}).runByTime(1).timethese().cmpthese();
}
}
Score:
guava: 1 wallclock secs ( 1.14 usr + 0.06 sys = 1.20 CPU) @ 972828.08/s (n=1168278)
commons: 1 wallclock secs ( 1.07 usr + 0.00 sys = 1.08 CPU) @ 39361.53/s (n=42403)
String.replace: 1 wallclock secs ( 1.07 usr + 0.01 sys = 1.08 CPU) @ 61647.92/s (n=66395)
Spring: 1 wallclock secs ( 1.02 usr + 0.00 sys = 1.03 CPU) @ 878340.23/s (n=901452)
Comparison chart:
Rate guava commons String.replace Spring
guava 972828/s -- 2372% 1478% 11%
commons 39362/s -96% -- -36% -96%
String.replace 61648/s -94% 57% -- -93%
Spring 878340/s -10% 2131% 1325% --
出力がとても見やすいので、どれが速いのか一目瞭然である。
コードは、Java 8 の lambda 式を利用することにより、annotation を利用した場合よりもさらに簡単に書けるようになっている。
Benchmark.java 自体が1ファイルなので、そのままコピペしてプロジェクトに突っ込んでつかうこともできる。