Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Extreme optimization

Posts: 239

I’ve been reading up on ways to optimize Lua and get the most out of performance.

The most common recommendation is “don’t”, but the second most common is “use locals”. Particularly this refers to having local pointers to functions.

Here I’ve made a simple test comparison of math.random. A note about the tests, Lua time stamps will only give us seconds as the smallest measurement. To compensate for this, I’ve made the test loops long enough to break into triple figures so we can see the timing differences better.

Also, these benefits are really only seen when running a call to these functions more than once. However it’s still a good thing to know I think.

-- Locals Performance Test local random = math.random local osTime = os.time function setup() setupRandom = math.random end function draw() background(40, 40, 50) end function touched(touch) local startTime, endTime if touch.state == ENDED then print('started') startTime = osTime() for i = 1, 4000000000 do math.random(1, 1000000) end endTime = osTime() print('math.random', endTime - startTime) local localRandom = math.random startTime = osTime() for i = 1, 4000000000 do localRandom(1, 1000000) end endTime = osTime() print('local', endTime - startTime) startTime = osTime() for i = 1, 4000000000 do setupRandom(1, 1000000) end endTime = osTime() print('setup', endTime - startTime) startTime = osTime() for i = 1, 4000000000 do random(1, 1000000) end endTime = osTime() print('global local', endTime - startTime) startTime = osTime() for i = 1, 4000000000 do otherRandom(1, 1000000) end endTime = osTime() print('other', endTime - startTime) end end

Note - otherRandom is defined as a global in another file

Results (lower is better):
direct use of math.random - 120 seconds
define local in same scope - 97
defined in setup() - 107
defined local in global scope - 101
defined global in another file - 115

Tagged:

• edited March 2021 Posts: 9,808

@skar Use socket to get time. Example below.

viewer.mode=STANDARD

function setup()
s=require("socket")
st=s:gettime()
for z=1,10000000 do
a=math.sqrt(z)
end
en=s:gettime()
print(en-st)

ss=math.sqrt
st=s:gettime()
for z=1,10000000 do
a=ss(z)
end
en=s:gettime()
print(en-st)

local ss=math.sqrt
st=s:gettime()
for z=1,10000000 do
a=ss(z)
end
en=s:gettime()
print(en-st)
end

• Posts: 239

Thanks a lot Dave. It’s strange, I came across using socket in different guides but it didn’t work for me, because I tried importing like this require “socket” not like this require(“socket”). Yet I’ve seen the former work in the Spine demo code, is the difference in local files vs system reference?

• Posts: 1,303

might be best to time an empty loop

• Posts: 239