Difference between revisions of "Optimizations"
From GiderosMobile
(Created page with "'''Supported platforms:''' File:Platform android.pngFile:Platform ios.pngFile:Platform mac.pngFile:Platform pc.pngFile:Platform html5.pngFile:Platform wi...") |
|||
(One intermediate revision by the same user not shown) | |||
Line 7: | Line 7: | ||
==== '''Distance''' ==== | ==== '''Distance''' ==== | ||
<syntaxhighlight lang="lua"> | <syntaxhighlight lang="lua"> | ||
− | -- simple functions test timer by @antix | + | -- distance (based on simple functions test timer by @antix) |
− | local random, sqrt = math.random, math.sqrt | + | local distance, random, sqrt = math.distance, math.random, math.sqrt |
− | local x1, y1 = random(- | + | local x1, y1, x2, y2 = random(-10000, 10000), random(-10000, 10000), random(-10000, 10000), random(-10000, 10000) |
− | + | ||
+ | -- classic (boring!) | ||
local dx, dy | local dx, dy | ||
+ | -- with vectors | ||
+ | local p1, p2 = vector(x1, y1), vector(x2, y2) | ||
− | -- init | + | -- init |
− | local dist = | + | local dist = distance(x1, y1, x2, y2) |
+ | print("") | ||
print("*** POINT A: "..x1, y1, "POINT B: "..x2, y2) | print("*** POINT A: "..x1, y1, "POINT B: "..x2, y2) | ||
− | print("*** DISTANCE: "..dist) | + | print("*** DISTANCE: "..dist) |
+ | |||
+ | dist = #(p2-p1) | ||
+ | print("*** VECTORS DIST.: "..dist) | ||
+ | print("") | ||
-- tests | -- tests | ||
local data = { | local data = { | ||
{ | { | ||
− | "sqrt", | + | "sqrt ", |
function() | function() | ||
dx, dy = x2-x1, y2-y1 | dx, dy = x2-x1, y2-y1 | ||
dist = sqrt(dx*dx + dy*dy) | dist = sqrt(dx*dx + dy*dy) | ||
− | end, -- | + | end, -- 50ms |
}, | }, | ||
{ | { | ||
− | "exponent", | + | "exponent ", |
function() | function() | ||
dx, dy = x2-x1, y2-y1 | dx, dy = x2-x1, y2-y1 | ||
dist = (dx^2 + dy^2)^0.5 | dist = (dx^2 + dy^2)^0.5 | ||
− | end, -- | + | end, -- 37ms |
}, | }, | ||
{ | { | ||
− | "multiply/exponent", | + | "multiply/exponent ", |
function() | function() | ||
dx, dy = x2-x1, y2-y1 | dx, dy = x2-x1, y2-y1 | ||
dist = (dx*dx + dy*dy)^0.5 | dist = (dx*dx + dy*dy)^0.5 | ||
− | end, -- | + | end, -- 40ms |
}, | }, | ||
{ | { | ||
Line 46: | Line 54: | ||
function() | function() | ||
dx, dy = x2-x1, y2-y1 | dx, dy = x2-x1, y2-y1 | ||
− | + | -- dist = dx*dx + dy*dy | |
− | end, -- | + | dist = dx^2 + dy^2 |
+ | end, -- 36ms but wrong result! | ||
}, | }, | ||
{ | { | ||
− | "math.distance", | + | "math.distance ", |
function() | function() | ||
− | dist = | + | dist = distance(x1, y1, x2, y2) |
− | end, -- | + | end, -- 53ms |
+ | }, | ||
+ | { | ||
+ | "Luau VECTORS ", | ||
+ | function() | ||
+ | dist = #(p2-p1) | ||
+ | end, -- 24ms => this is our WINNER (Gideros 2024.11+) | ||
}, | }, | ||
} | } | ||
− | + | ||
-- run all functions | -- run all functions | ||
for i = 1, #data do | for i = 1, #data do | ||
Line 66: | Line 81: | ||
end | end | ||
local elapsed = math.floor((os.timer() - start) * 1000) | local elapsed = math.floor((os.timer() - start) * 1000) | ||
− | print(block[1].." ("..elapsed.."ms) | + | print(block[1].." ("..elapsed.."ms)", "", "distance: "..dist) |
end | end | ||
+ | |||
+ | --[[ RESULTS | ||
+ | |||
+ | *** POINT A: -4709 7129 POINT B: 5172 7263 | ||
+ | *** DISTANCE: 9881.908570716489 | ||
+ | *** VECTORS DIST.: 9881.908520118976 | ||
+ | |||
+ | sqrt (50ms) distance: 9881.908570716489 | ||
+ | exponent (37ms) distance: 9881.908570716489 | ||
+ | multiply/exponent (40ms) distance: 9881.908570716489 | ||
+ | multiply/exponent without power (36ms) distance: 97652117 | ||
+ | math.distance (53ms) distance: 9881.908570716489 | ||
+ | Luau VECTORS (24ms) distance: 9881.908520118976]] | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 76: | Line 104: | ||
local sprites = {} | local sprites = {} | ||
+ | |||
for i = 1, 64 do | for i = 1, 64 do | ||
sprites[i] = {} | sprites[i] = {} | ||
Line 99: | Line 128: | ||
end | end | ||
end | end | ||
− | end, -- | + | end, -- 816ms (much better than addChildAt) |
}, | }, | ||
{ | { | ||
Line 110: | Line 139: | ||
end | end | ||
end | end | ||
− | end, -- | + | end, -- 1272ms |
+ | }, | ||
+ | { | ||
+ | "async swap", | ||
+ | function() | ||
+ | local function fun() | ||
+ | for _, v in pairs(sprites) do | ||
+ | if v.spr1:getY() < v.spr2:getY() then | ||
+ | spr1y, spr2y = v.spr1:getY(), v.spr2:getY() | ||
+ | stage:swapChildren(v.spr1, v.spr2) | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | Core.asyncCall(fun) -- profiler seems to be faster without asyncCall (because of pairs traversing?) | ||
+ | end, -- 29ms (the best but has some glitches!) | ||
}, | }, | ||
} | } | ||
Line 119: | Line 162: | ||
local func = block[2] | local func = block[2] | ||
local start = os.timer() | local start = os.timer() | ||
− | for i = 1, | + | for i = 1, 25000 do func() end -- 12500 |
local elapsed = math.floor((os.timer() - start) * 1000) | local elapsed = math.floor((os.timer() - start) * 1000) | ||
print(block[1].." ("..elapsed.."ms)", spr1y, spr2y) | print(block[1].." ("..elapsed.."ms)", spr1y, spr2y) |
Latest revision as of 17:37, 6 November 2024
Optimizations
When you're ready to optimize your game, this page can be helpful.
Distance
-- distance (based on simple functions test timer by @antix)
local distance, random, sqrt = math.distance, math.random, math.sqrt
local x1, y1, x2, y2 = random(-10000, 10000), random(-10000, 10000), random(-10000, 10000), random(-10000, 10000)
-- classic (boring!)
local dx, dy
-- with vectors
local p1, p2 = vector(x1, y1), vector(x2, y2)
-- init
local dist = distance(x1, y1, x2, y2)
print("")
print("*** POINT A: "..x1, y1, "POINT B: "..x2, y2)
print("*** DISTANCE: "..dist)
dist = #(p2-p1)
print("*** VECTORS DIST.: "..dist)
print("")
-- tests
local data = {
{
"sqrt ",
function()
dx, dy = x2-x1, y2-y1
dist = sqrt(dx*dx + dy*dy)
end, -- 50ms
},
{
"exponent ",
function()
dx, dy = x2-x1, y2-y1
dist = (dx^2 + dy^2)^0.5
end, -- 37ms
},
{
"multiply/exponent ",
function()
dx, dy = x2-x1, y2-y1
dist = (dx*dx + dy*dy)^0.5
end, -- 40ms
},
{
"multiply/exponent without power",
function()
dx, dy = x2-x1, y2-y1
-- dist = dx*dx + dy*dy
dist = dx^2 + dy^2
end, -- 36ms but wrong result!
},
{
"math.distance ",
function()
dist = distance(x1, y1, x2, y2)
end, -- 53ms
},
{
"Luau VECTORS ",
function()
dist = #(p2-p1)
end, -- 24ms => this is our WINNER (Gideros 2024.11+)
},
}
-- run all functions
for i = 1, #data do
local block = data[i]
local func = block[2]
local start = os.timer()
for i = 1, 1000000 do -- 1 million repetitions!
func()
end
local elapsed = math.floor((os.timer() - start) * 1000)
print(block[1].." ("..elapsed.."ms)", "", "distance: "..dist)
end
--[[ RESULTS
*** POINT A: -4709 7129 POINT B: 5172 7263
*** DISTANCE: 9881.908570716489
*** VECTORS DIST.: 9881.908520118976
sqrt (50ms) distance: 9881.908570716489
exponent (37ms) distance: 9881.908570716489
multiply/exponent (40ms) distance: 9881.908570716489
multiply/exponent without power (36ms) distance: 97652117
math.distance (53ms) distance: 9881.908570716489
Luau VECTORS (24ms) distance: 9881.908520118976]]
Sprite Sorting
-- sprite sorting (based on simple functions test timer by @antix)
local random = math.random
local sprites = {}
for i = 1, 64 do
sprites[i] = {}
sprites[i].spr1 = Pixel.new(0x0, 1, 64, 64)
sprites[i].spr1:setPosition(random(1, 640), 48) -- 48, 96
stage:addChild(sprites[i].spr1)
sprites[i].spr2 = Pixel.new(0xff0000, 1, 64, 64)
sprites[i].spr2:setPosition(random(1, 640), 64)
stage:addChild(sprites[i].spr2)
end
local spr1y, spr2y = 0, 0
-- tests
local data = {
{
"swap",
function()
for _, v in pairs(sprites) do
if v.spr1:getY() < v.spr2:getY() then
spr1y, spr2y = v.spr1:getY(), v.spr2:getY()
stage:swapChildren(v.spr1, v.spr2)
end
end
end, -- 816ms (much better than addChildAt)
},
{
"addChildAt",
function()
for _, v in pairs(sprites) do
if v.spr1:getY() < v.spr2:getY() then
spr1y, spr2y = v.spr1:getY(), v.spr2:getY()
stage:addChildAt(v.spr1, stage:getChildIndex(v.spr2))
end
end
end, -- 1272ms
},
{
"async swap",
function()
local function fun()
for _, v in pairs(sprites) do
if v.spr1:getY() < v.spr2:getY() then
spr1y, spr2y = v.spr1:getY(), v.spr2:getY()
stage:swapChildren(v.spr1, v.spr2)
end
end
end
Core.asyncCall(fun) -- profiler seems to be faster without asyncCall (because of pairs traversing?)
end, -- 29ms (the best but has some glitches!)
},
}
-- run all functions
for i = 1, #data do
local block = data[i]
local func = block[2]
local start = os.timer()
for i = 1, 25000 do func() end -- 12500
local elapsed = math.floor((os.timer() - start) * 1000)
print(block[1].." ("..elapsed.."ms)", spr1y, spr2y)
end
More to come, God's willing!