coffeecat wrote: ↑Sun Feb 11, 2018 1:15 pm
I can see a problem in pgimeno's benchmark code: math.random is slow, and could dominate the cost of the loop body.
It probably does. However, note that a) it's unlikely that the sign function appears alone in any computation-intensive process, therefore it makes the benchmark a bit less unrealistic, b) the test results are consistent even when the generator is seeded as suggested by Ivan and even when the order of the tests is changed, c) a different benchmark makes the branch function slightly slower (by a tight margin), showing that certain fine details could make a difference. If the performance of your game critically depends on a loop like that, you'd better be coding that game in C++.
coffeecat wrote: ↑Sun Feb 11, 2018 1:15 pm
Also note that all input numbers are integers.
Yes, otherwise it wouldn't be fair to include the clamp method. I've benchmarked with floats and excluding the clamp, same relative results.
coffeecat wrote: ↑Sun Feb 11, 2018 1:15 pmSorry, I thought math.huge is the maximum finite number representable in double. I think the clamp version is correct if it is (n * max_finite_double * max_finite_double)
No, floating-point numbers have a greater range near zero than near infinite, due to denormals:
The maximum finite value for double is (in Python):
Code: Select all
>>> float.fromhex('0x1.fffffffffffffp+1023')
1.7976931348623157e+308
But
Code: Select all
>>> float.fromhex('0x1.fffffffffffffp+1023') * 1e-310
0.0179769313486231
Edit: However, this would work:
Code: Select all
function sgn(x)
return math.max(-1, math.min(1, x/5e-324))
end
but that makes it substantially slower than the others in my tests.
Edit2: Oh wait, you said two products. Well, 1e200 works for that. And yeah, that's faster than the absdiv version always, and sometimes faster than the branch version.