Бенчмарк Java с эллиптической группой / Брент Бойер
Я пытаюсь использовать тест Java, который был упомянут здесь: https://www.ibm.com/developerworks/java/library/j-benchmark2/ и его можно скачать здесь: http://www.ellipticgroup.com/html/benchmarkingArticle.html
Я попытался использовать базовый пример в статье выше:
import bb.util.Benchmark;
public class ShortIndexesLoop {
public static void main(String[] args) throws Exception {
Callable<Integer> task =
new Callable<Integer>() { public Integer call() { return fibonacci(35); } };
System.out.println("fibonacci(35): " + new Benchmark(task));
}
protected static int fibonacci(int n) throws IllegalArgumentException {
if (n < 0) throw new IllegalArgumentException("n = " + n + " < 0");
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
Но каждое выполнение этого бенчмарка начинается с исключения, прежде чем он запускает бенчмарк
13 июня 2015 13:45:37 StringUtil ПРЕДУПРЕЖДЕНИЕ: строка не работает должным образом; увидеть причину
java.lang.Exception: substring does NOT share the same underlying char[] with its parent String
at bb.util.StringUtil.inspectStringConstructor(StringUtil.java:84)
at bb.util.StringUtil.<clinit>(StringUtil.java:75)
at bb.io.ConsoleUtil.<clinit>(ConsoleUtil.java:81)
at bb.util.Benchmark.sendUserMsg(Benchmark.java:1002)
at bb.util.Benchmark.osSpecificPreparation(Benchmark.java:579)
at bb.util.Benchmark.perform(Benchmark.java:541)
at bb.util.Benchmark.<init>(Benchmark.java:464)
at bb.util.Benchmark.<init>(Benchmark.java:439)
at ShortIndexesLoop.main(fib.java:13)
кажется, что любой вызов эталонного теста заканчивается использованием следующего метода в StringUtil
private static final boolean stringContructorTrimsGarbage = inspectStringConstructor();
private static boolean inspectStringConstructor() {
try {
// first prove that substring shares the same underlying char[] as the parent String:
String s1 = "abc123def";
String s2 = s1.substring(3, 6);
char[] value1 = (char[]) ReflectUtil.get(s1, "value");
char[] value2 = (char[]) ReflectUtil.get(s2, "value");
if (value1 != value2) throw new Exception("substring does NOT share the same underlying char[] with its parent String");
if (value2.length != s1.length()) throw new Exception("value2.length = " + value2.length + " != s1.length() = " + s1.length());
// second prove that the String(String) constructor trims garbage chars:
String s3 = new String(s2);
char[] value3 = (char[]) ReflectUtil.get(s3, "value");
if (value3 == value2) throw new Exception("new String shares the same underlying char[] with its String arg");
if (!(value3.length < value2.length)) throw new Exception("value3.length = " + value3.length + " is not < value2.length = " + value2.length);
return true;
}
catch (Exception e) {
LogUtil.getLogger2().logp(Level.WARNING, "StringUtil", "<clinit>", "String does not behave as expected; see cause", e);
return false;
}
}
Я не против этого исключения, поскольку библиотека тестов производительности дает результат. Однако попытка скомпилировать этот код для jar и запустить его как jar, является проблемой. Из-за исключения остальная часть кода не будет выполняться в терминале
У кого-нибудь есть идеи, как решить эту проблему?
1 ответ
Я знаю, что это старый вопрос, но, возможно, мое решение полезно и для других: в источнике StringUtil
Класс этого эталонного каркаса, задокументировано, почему эта проверка проводится. Исходя из этого, если у вас есть JDK, где substring
создает копию соответствующей части базового массива char, вы можете просто закомментировать stringContructorTrimsGarbage
флаг, а в newString
метод, вы просто возвращаете s.