Hi DevForumers, a while ago I had a question: Even if it’s a thousandth better, does performing mathematical operations on hexadecimal result in better performance than using decimal?
I tried out this question in mind with a little benchmark test, inputted below.
local timeNow = tick()
local hexNumber = 0x1F04864B + 0x1F04864B
print(hexNumber)
warn(tick()-timeNow) --> 0.00006413459777832031
local _TimeNow = tick()
local Number = 520390219 + 520390219
print(Number)
warn(tick()-_TimeNow) --> 0.000022172927856445312
I was rather confused by the results, expecting operations on hexadecimal to result in shorter times than that of operations on decimal… IIRC the results elsewhere concluded that hexadecimal was faster than decimal, though with binary being the fastest.
Was the source I read false or is LuaU different in some way? Why is it that hexadecimal is slower than decimal?
When you run performance tests like these it’s a good idea to do many of them, since the amount of time it takes to do a basic arithmetic operation is tiny.
On the machine level, there is no difference between a number that is defined in decimal or hexadecimal. The only time difference might theoretically come from how long it may take the compiler/interpreter to translate a number to machine code depending on whether it was defined in decimal or hex.
The code I used:
local n = 1000000 -- number of tests
wait(5) -- let other roblox scripts start up
local t = 0
for i = 1, n do
if (i % 10000 == 0) then wait() end
local now = tick()
local test = 0x1F04864B + 0x1F04864B
t = t + tick() - now
end
print("hex add:", t / n)
t = 0
for i = 1, n do
if (i % 10000 == 0) then wait() end
local now = tick()
local test = 520390219 + 520390219
t = t + tick() - now
end
print("dec add:", t / n)
t = 0
for i = 1, n do
if (i % 10000 == 0) then wait() end
local now = tick()
local test = 0x1F04864B * 0x1F04864B
t = t + tick() - now
end
print("hex mult:", t / n)
t = 0
for i = 1, n do
if (i % 10000 == 0) then wait() end
local now = tick()
local test = 520390219 * 520390219
t = t + tick() - now
end
print("dec mult:", t / n)
t = 0
for i = 1, n do
if (i % 10000 == 0) then wait() end
local now = tick()
local test = 0x1F04864B / 0x1F04864B
t = t + tick() - now
end
print("hex div:", t / n)
t = 0
for i = 1, n do
if (i % 10000 == 0) then wait() end
local now = tick()
local test = 520390219 / 520390219
t = t + tick() - now
end
print("dec div:", t / n)
The results:
hex add: 2.8787612915039063e-08
dec add: 2.8634309768676758e-08
hex mult: 2.8858184814453124e-08
dec mult: 2.8642654418945314e-08
hex div: 2.8728961944580077e-08
dec div: 2.8785228729248045e-08
It doesn’t appear very conclusive. The differences start after the ninth decimal place, which is miniscule, and can lean either way.
Really interesting, thank you for both your tips on benchmarking as well as the solution! I had assumed previously that hexadecimal was a quicker translation process into machine code than decimal, though, I still have a question. On a video, it used hexadecimal (0x5f3759df) for a number (1597463007) and performed various operations on it. I was wondering why this was so and why the author didn’t use the value in decimal to do such with it. Is there a valid reason behind this, or is it by preference?
if you’re doing advanced operations like bit shifts, bit masks and bit operations then it makes total sense to use hexadecimal or binary values. Also in lower level languages, using numbers that powers of 2 like 2, 4, 8, 16, 1024, 8096… is faster and more accurate since dividing by those numbers is really simple, is just shifting some bits around.
But all of this crazy optimizations and stuff doesn’t apply to our modern days of programming especially for modern languages and even more for interpreted (scripting) languages.
When you’re using a interpreted language like Lua and Python, Don’t even try such minimal optimizations since a lot of times it just results in the opposite effect.
hexadecimal numbers is really related to binary, but programmers prefer hexadecimal values since it’s more concise and easier to read and reason about.
for example
Dec( 255 ) = Hex( FF ) = Bin( 11111111 )
where every F in hex basically represents 1111 in binary
so one character to represent 4 bits is really powerful