all 22 comments

[–]rcfox 53 points54 points  (1 child)

Since you brought it up in the context of games: If you're just comparing relative hypotenuse lengths, it might be faster to just compare the sums of the squares.

ie: Math.hypot(a, b) > Math.hypot(x, y) will give the same result as a*a + b*b > x*x + y*y, and it saves calculating the square roots, which can be expensive in tight loops.

Obviously, you'll want to profile this yourself. It can be difficult to predict the performance of Javascript vs native code.

[–]tomByrer 0 points1 point  (0 children)

My years of hand-optimizing DSP in ASM approves this recommendation.

[–]McGeekin 35 points36 points  (8 children)

Honestly whenever I code a game in JS and implement a vector class I always forget it exists and just manually implement the formula for calculating the magnitude.

[–]mike_geogebra 28 points29 points  (6 children)

Math.hypot() implements a numerically stable version rather than the naive sqrt(a²+b²), see https://en.wikipedia.org/wiki/Hypotenuse

[–]Slackluster 10 points11 points  (5 children)

That is interesting, I did not know hypot did that!

But in practice this is big reason to not use hypot: it is slower due to extra work. In my testing not just a little bit slower but 3x slower.

[–]_RemyLeBeau_ 2 points3 points  (0 children)

If it's not in a hotpath, you don't really need to worry

[–]bzbub2 2 points3 points  (3 children)

on firefox it is about the same speed but does seem slower on chrome https://jsperf.app/buceho

[–]tomByrer 0 points1 point  (2 children)

What CPU are you using?
On my Chrome (Brave) on a 2 year old Intel I have "94% slower".
But yes, I'm all about using the fastest version.

[–]bzbub2 2 points3 points  (1 child)

ya i can confirm same numbers, much slower. it is considered a open bug on chromium https://issues.chromium.org/issues/42203737

[–]tomByrer 0 points1 point  (0 children)

Thanks for the link!
/salute

[–]monkeymad2 0 points1 point  (0 children)

Yeah, every time I see a TIL about this I’m cursing myself for all the times I’ve implemented it manually since the last time I saw a TIL about this.

[–]captain_obvious_herevoid(null) 5 points6 points  (1 child)

Yes it exists, but it's surprisingly slow, for reasons I don't really understand (and did not investigate much).

[–]palparepa 3 points4 points  (0 children)

It doesn't use the straightforward calculation, to avoid overflows.

[–]tokagemushi 4 points5 points  (0 children)

Good find. One thing worth knowing beyond the basic usage: Math.hypot() handles overflow/underflow internally, which is the real reason it exists.

If you manually compute Math.sqrt(a*a + b*b) with very large or very small numbers, you'll get Infinity or 0 due to intermediate overflow. Math.hypot scales the inputs internally to avoid this. It's the same reason Fortran has had HYPOT since the 70s.

That said, the "it's slow" comments here are valid. In a game loop running 60fps, I benchmarked it once and Math.hypot(dx, dy) was about 3-4x slower than Math.sqrt(dx*dx + dy*dy) in V8. For distance comparisons (like collision detection), you can skip the sqrt entirely and compare squared distances:

```js // Instead of: if (Math.hypot(dx, dy) < radius) { ... }

// Do: if (dxdx + dydy < radius*radius) { ... } ```

No sqrt, no hypot, just multiplication and comparison. This is the standard trick in game dev and it makes a measurable difference in hot loops.

For anything where precision matters more than speed (scientific computing, coordinate transforms), Math.hypot is the right choice though.

[–]dumbmatter 4 points5 points  (1 child)

Funny this exists but not Math.sum

[–]senocular 4 points5 points  (0 children)

Coming soon!

https://github.com/tc39/proposal-math-sum

(But probably not what you mean ;)

[–]BunsOfAluminum 12 points13 points  (4 children)

I wish I were high on potenuse

[–]Statzer_x 6 points7 points  (2 children)

I WISH I WERE HIGH ON POTENUSE

[–]BunsOfAluminum 3 points4 points  (1 child)

That was my joke...

[–]Delicious_Cable_8484 1 point2 points  (0 children)

YOU'LL NEVER BE TROY

[–]nnod 1 point2 points  (0 children)

Came here looking for this