- A Concurrent Affair - https://www.concurrentaffair.org -

New Mint Benchmarks: Overhead of Boxing/Unboxing

I was working on the next tutorial for the Java Mint Blog [1], and in writing some new small programs realized that boxing and unboxing has a pretty large impact. It is much better to use primitive types. That also implies that we can’t use generics for the staged function.

This generic ILambda with R=Double, P=Double has bad performance:

Code> codePowerOf17 =
<| new ILambda() {
public Double apply(Double param) {
return `(spower(<|param|>,17));
}
} |>;
ILambda stagedPowerOf17 = codePowerOf17.run();

This non-generic ILambda_double_double where return type and parameter type are fixed to primitive double is much better:

Code primCodePowerOf17 =
<| new ILambda_double_double() { public double apply(double param) { return `(spower(<|param|>,17));
}
} |>;

% mint BoxingUnboxingExpense
power(2, 17)
       10818348
stagedPowerOf17.apply(2.0)
       10452177
primStagedPowerOf17.apply(2.0)
       43746

This is for 200 million iterations. With boxing/unboxing overhead, the staged function barely breaks even.

I rewrote the benchmarking code to put less emphasis on the boxing/unboxing and re-ran our benchmarks. A lot of them stayed the same, but some power and fib_let gained another factor of two!

power                   9.066x (up from 4.552)
fib_let                 8.834x (up from 4.107)
eval-fact               10.384x (up from 8.390)
loop-unroll             1.580x (slightly up from 1.439)
power_let               5.703x (about same)
partial-loop-unroll     0.965x (about same, 0.942x)
serialize               18.433x (about same)
mmult                   0.913x (slightly down from 1.180)
mmult-sparse            1.134x (slightly down from 1.469)
eval-fib                9.911x (slightly down 10.210)
[2] [3]Share [4]