java benchmark with Ellipticgroup / Brent Boyer

159 views Asked by At

I am trying to use the java benchmark that was mentioned here: https://www.ibm.com/developerworks/java/library/j-benchmark2/ and that can be downloaded here: http://www.ellipticgroup.com/html/benchmarkingArticle.html

I tried to use the basic example in the article above:

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);
    }
}

But every execution of this benchmark starts with an exception before it is running the benchmark

Jun 13, 2015 1:45:37 PM StringUtil WARNING: String does not behave as expected; see cause

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)

it seems that any call to the benchmark ends up using the following method in 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;
    }
}

I don't really mind the exception, since the benchmark library do give a result. However, trying to compile this code to jar and running it as a jar, is a problem. Due to the exception the rest of the code won't be executed in the terminal

Anyone has any idea how to solve this issue?

1

There are 1 answers

0
gabor On

I know it is an old question, but mabye my solution is useful for others as well: In the source of the StringUtil class of this benchmark framework, it is documented, why this inspection is done. Based on this, if you have a JDK where substring creates a copy of the relevant part of the underlying char array, you can simply comment the stringContructorTrimsGarbage flag, and in the newString method, you simply return s.