Clockwise Triangles Performance: Addendum
A quick update on my previous article.
Nicholas Wilcox (@redbluemonkey) on Twitter made a very good point:
Do you need a full sort, or do you just need to reverse the order if it doesn't already have the correct winding? You can check the winding of any polygon with only the first 3 points using a cross product.
— Nicholas Wilcox (@redbluemonkey) July 26, 2020
I might need a full sort for polygons, but with a focus on triangles right now this sounded like a good idea to investigate. Am I being nerd-sniped? Hmm.
Here's the new code as a method on the Triangle
struct we defined
previously:
The determinant
calculation is an optimised version of the formula presented
here. It's actually the
doubled area of the triangle where counter-clockwise triangles produce negative values. This
behaviour is useful because we can just swap two of the triangle's points to make it clockwise if
the result is negative.
If the determinant is zero, the triangle is colinear. In this instance, we'll sort the triangle's points in ascending Y then X direction. This ensures the points always lie on the single line in order.
The sort_yx
function above is implemented like this:
/// Sort 3 points in order of increasing Y value. If two points have the same Y value, the one with
/// the lesser X value is put before.
Benchmarks
Here's the table from the original investigation with this new method added in:
Suite | Result (avg) |
---|---|
Straight C port (baseline) | 9.4473 ns |
Use Ordering instead of bool | 10.712 ns |
Hoist some repeated comparisons | 10.160 ns |
Convert everything to a big, single match | 12.024 ns |
Simplified algorithm | 2.9 ns |
A huge improvement! Thanks internet!
And we didn't even need to look at the generated assembly.