Can someone explain what is going on with this square rooting?

Hi

Dealing with vectors using floats but using Math.sqrt() and a cast to find magnitude, etc., I started to wonder if wasting the extra digits from the returned double was ‘okay’ and if it could be done any faster. So some reading and testing different methods and I largely realised I won’t beat hardware but then some strange things happened. See here:

https://gist.github.com/danieldean/5d2abab25bc9b8041d1e

When run the method ‘slow()’ which I named so because I though it would be, frequently out performs Java’s native methods with negligible difference in accuracy. Clearly it would stray off as numbers go higher but if it were tuned to the application is this not going to prove faster?

I probably would never bother using anything but Math.sqrt() but I’d like to know what’s going on here… ???

You really really really shouldn’t try to fix performance when you don’t have performance issues. About the only time sqrt is going to matter in performance is if you do software lighting and transformations. Which these days you shouldn’t be doing. At least not much.

Also you are doing microbenchmarks which are almost always wrong.

using approx squares is totally fine … http://en.wikipedia.org/wiki/Fast_inverse_square_root

but using this early in the process is just annoying. Math.sqrt will always yield ‘good’ resulsts while hacky approximations only work in limited ranges - but they are faster in the end.

i guess your excessive use of System.nanoTime is screwing up your numbers. :clue:

I’m not actually trying to ‘fix it’, this is purely out of interest. I’m aware there are probably many pitfalls which is why I’ve asked so that I may learn… something to do with the timing being wrong is my assumption.

nanoTime() is fairly inaccurate in most cases. It’s better to use getTimeMillis(). (generally) Edit: <-- bad advice… my bad.

Also, to get a good read on how accurate a benchmark is you’ll need to run timings on millions/billions of operations, even then there are so many factors that come into play on computers, not even mentioning the JVM, that it’s difficult at best.

I fell into this a while ago and finally gave up, because my square roots are negligible compare to other parts of my code.

Really? I have the exact opposite experience. On some Windows machines getTimeMillis() as an actual accuracy of around 15ms, e.g. the timer only updates every 15ms, so you get horrible precision. nanoTime() has always worked reliably for me.

Maybe that was just a brainfart, but don’t use getTimeMillis(). nanoTime() is superior.

I think you’re confusing my meaning, nanoTime() has better precision, currentTimeMillis() (I screwed up the name) has better accuracy.

Also, I wouldn’t say that nanoTime() is superior as it’s not thread safe and if you call nanoTime() and get 443452 then call nanoTime() a nano second later you aren’t guaranteed to get 443453…

Don’t get me wrong they both have their uses, but nanoTime() is not accurate. Also if you’re measuring differences in performance by nano seconds you’re doing it wrong anyway.

Edit: I lied! I forgot about including the JVM, use nanoTime() unless you can’t…

Hotspot emits ‘sqrtss’ if you properly write your code. Doing anything else will be slower.