Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A faster implementation for Math.abs(a - b) - Math.abs(c - d)?

I have a Java method that repeatedly evaluates the following expression in a very tight loop with a large number of repetitions:

Math.abs(a - b) - Math.abs(c - d)

a, b, c and d are long values that can span the whole range of their type. They are different in each loop iteration and they do not satisfy any invariant that I know of.

The profiler indicates that a significant portion of the processor time is spent in this method. While I will pursue other avenues of optimization first, I was wondering if there is a smarter way to calculate the aforementioned expression.

Apart from inlining the Math.abs() calls manually for a very slight (if any) performance gain, is there any mathematical trick that I could use to speed-up the evaluation of this expression?

like image 257
thkala Avatar asked Feb 22 '23 19:02

thkala


1 Answers

I suspect the profiler isn't giving you a true result as it trying to profile (and thus adding over head to) such a trivial "method". Without the profile Math.abs can be turned into a small number of machine code instructions, and you won't be able to make it faster than that.

I suggest you do a micro-benchmark to confirm this. I would expect loading the data to be an order of magnitude more expensive.

long a = 10, b = 6, c = -2, d = 3;

int runs = 1000 * 1000 * 1000;
long start = System.nanoTime();
for (int i = 0; i < runs; i += 2) {
    long r = Math.abs(i - a) - Math.abs(c - i);
    long r2 = Math.abs(i - b) - Math.abs(d - i);
    if (r + r2 < Integer.MIN_VALUE) throw new AssertionError();
}
long time = System.nanoTime() - start;
System.out.printf("Took an average of %.1f ns per abs-abs. %n", (double) time / runs);

prints

Took an average of 0.9 ns per abs-abs. 
like image 81
Peter Lawrey Avatar answered Feb 27 '23 16:02

Peter Lawrey