import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
class FormatPerformance {
/**
* ループ回数(100万回)
*/
private final int LOOP = 1000 * 1000;
private static final ThreadLocalRandom random = ThreadLocalRandom.current();
public static void main(String[] args) {
FormatPerformance fp = new FormatPerformance();
System.out.println("===== benchmark1 =====");
fp.benchmark1();
System.out.println("");
System.out.println("===== benchmark2 =====");
fp.benchmark2();
}
/**
* ランダムな文字列を返します
*
* @return ランダムなアルファベット文字列
*/
private String randomString() {
final int size = random.nextInt(16) + 1;
StringBuilder sb = new StringBuilder(size);
for (int i = 0; i < size; i++) {
sb.append((char)('a' + random.nextInt(26)));
}
return sb.toString();
}
/**
* 書式変換ベンチ<br>
* {@link String#format(String, Object...)} vs {@link MessageFormat#format(String, Object...)}
*/
private void benchmark1() {
final String[][] expects = { { "すごーい! %sは%sが得意なフレンズなんだね!", "IPアドレス %d.%d.%d.%d/%d" },
{ "すごーい! {0}は{1}が得意なフレンズなんだね!", "IPアドレス {0}.{1}.{2}.{3}/{4}" }, };
long totalByConcat = 0;
long totalByString = 0;
long totalByMessage = 0;
for (int i = 0; i < LOOP; i++) {
String paramStr1 = randomString();
String paramStr2 = randomString();
int paramInt1 = random.nextInt(255);
int paramInt2 = random.nextInt(255);
int paramInt3 = random.nextInt(255);
int paramInt4 = random.nextInt(255);
int paramInt5 = random.nextInt(32);
List<String> list = new ArrayList<>();
// 文字列結合
{
long begin = System.nanoTime();
String sugoi = "すごーい! " + paramStr1 + "は" + paramStr2 + "が得意なフレンズなんだね!";
String ipAddress = "IPアドレス " + Integer.toString(paramInt1) + "." + Integer.toString(paramInt2) + "."
+ Integer.toString(paramInt3) + "." + Integer.toString(paramInt4) + "/"
+ Integer.toString(paramInt5);
totalByConcat += System.nanoTime() - begin;
list.add(sugoi);
list.add(ipAddress);
}
// String#format(String, Object...)
{
long begin = System.nanoTime();
String sugoi = String.format(expects[0][0], paramStr1, paramStr2);
String ipAddress = String.format(expects[0][1], paramInt1, paramInt2, paramInt3, paramInt4, paramInt5);
totalByString += System.nanoTime() - begin;
list.add(sugoi);
list.add(ipAddress);
}
// MessageFormat#format(String, Object...)
{
long begin = System.nanoTime();
String sugoi = MessageFormat.format(expects[1][0], paramStr1, paramStr2);
String ipAddress = MessageFormat.format(expects[1][1], paramInt1, paramInt2, paramInt3, paramInt4, paramInt5);
totalByMessage += System.nanoTime() - begin;
list.add(sugoi);
list.add(ipAddress);
}
}
System.out.println(String.format("String concatenation average = %d[ns]", totalByConcat / LOOP));
System.out.println(String.format("String#format(String, Object...) average = %d[ns]", totalByString / LOOP));
System.out.println(String.format("MessageFormat#format(String, Object...) average = %d[ns]", totalByMessage / LOOP));
}
/**
* 書式変換した文字列を蓄積するベンチ<br>
* {@link String#format(String, Object...)} vs {@link Formatter#format(String, Object...)}
*/
private void benchmark2() {
final String[] expects = { "すごーい! %sは%sが得意なフレンズなんだね!", "IPアドレス %d.%d.%d.%d/%d" };
long totalByString = 0;
long totalByFormatter = 0;
for (int i = 0; i < LOOP; i++) {
String paramStr1 = randomString();
String paramStr2 = randomString();
int paramInt1 = random.nextInt(255);
int paramInt2 = random.nextInt(255);
int paramInt3 = random.nextInt(255);
int paramInt4 = random.nextInt(255);
int paramInt5 = random.nextInt(32);
// StringBuilder + String#format
{
long begin = System.nanoTime();
StringBuilder sb = new StringBuilder();
sb.append(String.format(expects[0], paramStr1, paramStr2));
sb.append(String.format(expects[1], paramInt1, paramInt2, paramInt3, paramInt4, paramInt5));
totalByString += System.nanoTime() - begin;
}
// Formatter#format
{
long begin = System.nanoTime();
try (Formatter formatter = new Formatter();) {
formatter.format(expects[0], paramStr1, paramStr2);
formatter.format(expects[1], paramInt1, paramInt2, paramInt3, paramInt4, paramInt5);
}
totalByFormatter += System.nanoTime() - begin;
}
}
System.out.println(String.format("String#format(String, Object...) average = %d[ns]", totalByString / LOOP));
System.out.println(String.format("Formatter#format(String, Object...) average = %d[ns]", totalByFormatter / LOOP));
}
}