- Joined
- Jan 23, 2015
- Messages
- 124
I've been asked to check several statements about LUA, so here's a bunch of tests and benchmarks from me.
This compilation might be supplemented should any questions appear. Ask any!
I'm using Trokkin/CeresStdLib for utility.
This compilation might be supplemented should any questions appear. Ask any!
I'm using Trokkin/CeresStdLib for utility.
This test shows that coroutines are not multithreaded and could even be seen as direct function calls.
Which is pretty expected results, that we don't have proper multithreading here, considering wc3 net architecture.
Which is pretty expected results, that we don't have proper multithreading here, considering wc3 net architecture.
Code:
busy = false
multithreaded = false
function a(n)
local i = 0
if busy then
multithreaded = true
end
busy = true
while i < 1000000 do
i = i + 1
end
busy = false
print("Thread #" .. n .. " finished it's work")
end
function check()
if busy then
print("Still busy")
end
if multithreaded then
print("We're multithreaded!")
else
print("We're not multithreaded :(")
end
end
init(function ()
for i = 1,10 do
coroutine.resume(coroutine.create(a), i)
end
check()
TimerStart(CreateTimer(), 0.00, false, check)
TimerStart(CreateTimer(), 1.00, false, check)
end)
Yay, dynamic Lua execution.
Code:
shell = CreateTrigger()
TriggerRegisterPlayerChatEvent(shell, Player(0), '%', false)
TriggerAddAction(shell, function()
local s = GetEventPlayerChatString()
s = SubString(s, 1, StringLength(s))
local f = load(s)
if not f then
print('invalid shell command \'' .. s .. '\'')
end
f()
end)
This test takes a lot of time to iterate 2^31 times but proves the statement.
Meanwhile, JASS outputs 230768 on an equivalent test.
Meanwhile, JASS outputs 230768 on an equivalent test.
Code:
i = 0
function a()
while i < 2147483647 do
i = i + 1
end
end
function check()
print(i)
end
init(function()
TimerStart(CreateTimer(), 0.00, false, check)
a()
end)
Please note that results are highly prone to errors, I never get same result twice. I estimate precision to be +-3% of 'true' value.
Also, never compare language feature tests done on different machines.
Results (ms / sec per 1e6 calls):
Also, never compare language feature tests done on different machines.
Results (ms / sec per 1e6 calls):
- nothing -> 0.025
- test -> 0,0923
- direct call -> 0,1164
- indirect call -> 0,1159
- indirect call #2 -> 0,1176
- indirect call #3 -> 0,1190
- indirect call #4 -> 0,1176
- coroutines -> 3,636
- coroutines #2 -> 2,143
- pcall -> 0,1530
- pcall #2 -> 0,1770
- pcall #3 -> 3,345
- pcall #4 -> 5,070
- ForForce -> 3,550
Code:
init(function()
local function test()
for i=1,10 do
end
end
benchmark('nothing', function() end)
benchmark('test', test)
benchmark('direct call', function()
test()
end)
local f = test
benchmark('indirect call', function()
f()
end)
local f = function()
for i=1,10 do
end
end
benchmark('indirect call #2', function()
f()
end)
local arr = {}
arr[0] = function ()
for i=1,10 do
end
end
arr[1] = test
benchmark('indirect call #3', function()
arr[0]()
end)
benchmark('indirect call #4', function()
arr[1]()
end)
benchmark('coroutines', function()
local c = coroutine.create(test)
coroutine.resume(c)
end)
local c = coroutine.create(function ()
while true do
test()
coroutine.yield()
end
end)
benchmark('coroutines #2', function()
coroutine.resume(c)
end)
benchmark('pcall', function()
pcall(test)
end)
benchmark('pcall #2', function()
pcall(function ()
test()
end)
end)
benchmark('pcall #3', function()
pcall(function ()
test()
error("oops")
end)
end)
benchmark('pcall #3', function()
pcall(function ()
test()
a = "a" + 1 -- error: attempt to perform arithmetic on a string value
end)
end)
local force = CreateForce()
ForceAddPlayer(force, GetLocalPlayer())
benchmark('ForForce', function()
ForForce(force, test)
end)
DestroyForce(force)
end)
Code:
replaceNative("Player", function(i) return players[i] end)
ceres.addHook("main::before", function()
localplayer = GetLocalPlayer()
replaceNative("GetLocalPlayer", function() return localplayer end)
end)
Results (ms / sec per 1e6 calls):
- GetLocalPlayer() -> 0.062
- Player(0) -> 0,079
- Native.GetLocalPlayer() -> 0,402
- Native.Player(0) -> 2,336
- players[0] -> 0,057
- localplayer -> 0,048
Code:
init(function()
benchmark(
'GetLocalPlayer()',
function()
local a = GetLocalPlayer()
end
)
benchmark(
'Player(0)',
function()
local a = Player(0)
end
)
benchmark(
'Native.GetLocalPlayer()',
function()
local a = Native.GetLocalPlayer()
end
)
benchmark(
'Native.Player(0)',
function()
local a = Native.Player(0)
end
)
benchmark(
'localplayer',
function()
local a = localplayer
end
)
benchmark(
'players[0]',
function()
local a = players[0]
end
)
end)
Result - 4,302 vs 3,854
10% advantage in favor of not using JASS again.
10% advantage in favor of not using JASS again.
Code:
local time1 = 0
local time2 = 0
local function benchmark_timers()
doAfter(0.01, function()
local clock
local start
doAfter(0, function()
clock = os.clock
start = clock()
end)
for i = 1, 10000 do
TimerStart(CreateTimer(), 0, false, function()
DestroyTimer(GetExpiredTimer())
end)
end
doAfter(0, function()
time1 = time1 + (clock() - start)
end)
end)
doAfter(0.02, function()
local clock
local start
doAfter(0, function()
clock = os.clock
start = clock()
end)
for i = 1, 10000 do
local t = CreateTimer()
TimerStart(t, 0, false, function()
DestroyTimer(t)
end)
end
doAfter(0, function()
time2 = time2 + (clock() - start)
end)
end)
end
init(function()
doPeriodicalyCounted(0.03, 100, benchmark_timers)
doAfter(3, function()
Log.info(time1 .. ' vs ' .. time2)
end)
end)
Last edited: