Reputation: 353
The standard Math.sqrt()
method seems pretty fast in Java already, but it has the inherent drawback that it is always going to involve 64-bit operations which does nothing but reduce speed when dealing with 32-bit float
values. Is it possible to do better with a custom method that uses a float
as a parameter, performs 32-bit operations only, and returns a float
as a result?
I saw:
Fast sqrt in Java at the expense of accuracy
and it did little more than reinforce the notion that Math.sqrt() is generally hard-to-beat. I also saw:
http://www.codeproject.com/Articles/69941/Best-Square-Root-Method-Algorithm-Function-Precisi
which showed me a bunch of interesting C++/ASM hacks that I am simply too ignorant to port directly to Java. Though sqrt14 might be interesting as a part of a JNI call . . .
I also looked at Apache Commons FastMath, but it looks like that library defaults to the standard Math.sqrt() so no help there. And then there's Yeppp!:
but I haven't bothered with that yet.
Upvotes: 7
Views: 759
Reputation: 98330
You need nothing to speed up sqrt
for 32-bit values. HotSpot JVM does it automatically for you.
JIT compiler is smart enough to recognize f2d -> Math.sqrt() -> d2f
pattern and replace it with faster sqrtss
CPU instruction instead of sqrtsd
. The source.
The benchmark:
@State(Scope.Benchmark)
public class Sqrt {
double d = Math.random();
float f = (float) d;
@Benchmark
public double sqrtD() {
return Math.sqrt(d);
}
@Benchmark
public float sqrtF() {
return (float) Math.sqrt(f);
}
}
And the results:
Benchmark Mode Cnt Score Error Units
Sqrt.sqrtD thrpt 5 145501,072 ± 2211,666 ops/ms
Sqrt.sqrtF thrpt 5 223657,110 ± 2268,735 ops/ms
Upvotes: 6
Reputation: 36352
As you seem to know JNI:
just write a minimal wrapper for double sqrt(double)
and float sqrt(float)
from C's standard library's math.h
and compare performance.
Hint: you won't feel a difference unless you do a lot of square rooting, and then the performance advantage of using SIMD instructions to do multiple sqrts at once will most probably dominate the effects. You will need to get a memory-aligned array of the floating point values from Java, which can be quite hard, if you're using Java standard libraries.
Upvotes: 0