I’ve been trying to optimize some NPCs I am making which require doing a lot of distance checks between players and other NPCs.
I always thought magnitude checks were relatively expensive due to the square root operation that happens, and a common method for making it faster was to just compare the non-squared rooted distance with the squared distance of what you’re comparing (e.g. if you’re checking if an NPC is less than 50 studs away from a player, you would check if the difference of positions is less than 50^2).
However, I did some benchmarking in studio where I compared the min, average and max times to compute 10,000,000 square roots against 10,000,000 squares, and found that square rooting was actually faster, with square rooting taking about 65% of the time (on average) that squaring took.
Is there some secret optimisation that roblox has done which has made this a lot faster?
I’m not asking how to do a distance check. I’m talking about optimisation regarding distance checks. And the relative cost between computing square roots vs squaring.
local val = 0
local multTime = 0
local sqrtTime = 0
for _ = 1, 10 do
local clock_start = os.clock()
for i = 1, 1000000 do
val = i*i
end
local timeTaken = os.clock() - clock_start
multTime += timeTaken
clock_start = os.clock()
for i = 1, 1000000 do
val = math.sqrt(i)
end
timeTaken = os.clock() - clock_start
sqrtTime += timeTaken
end
print('mult time taken: ' .. multTime)
print('sqrt time taken: ' .. sqrtTime)
Different designs in FPUs might yield faster results for square-rooting doubles (IEEE754 requires a native sqrt instruction on complying CPUs).
However, if the magnitude you’re comparing is constant, then skipping the square-root is definitely going to be faster. Non-constant comparisons may differ depending on platform, so just choose the most convenient in those cases.
If it isn’t too work intensive, I’d be interested to see a basic, vector-based method added to your comparison (as was posted above), which is what I assume most would default to.
Lua also has the ^ operator, which can do everything math.pow can but as a VM instruction instead of a library call. Squaring and square-rooting with it is consistently faster because of that.