Lua Performance

Tiramisu

Warlord
Joined
Aug 16, 2013
Messages
148
Location
Leonberg (BW, Germany)
Currently I am trying to create an A*-pathfinding Algorithm in Lua, but I am having huge performance problems.
So now I wonder which Lua operations take the most calculation time.

I have found out that using tables too many times can cost a huge amount of performance, so you should better use numbers instead of tables if possible (e.g. using the Index number of a plot or its coordinates instead of the Lua object of the plot itself). This insight is kind of obvious.
However, there are many other details that I wanted to find out about performance in Lua. So I have created the following test function, which I am using in Firetuner as an action control:

Code:
local iDeltaSeconds = 1

local x = os.clock()
local n = 0
while os.clock() < x + iDeltaSeconds do
    n = n + 1
    --------------------
    --insert test code here
    --------------------
end
print("n: " .. n)
It works like this: First I put some code in place of
Code:
--insert test code here
Then I take a look at the results in the log to see how many times this code could be executed within iDeltaSeconds, which is 1 second here.

At first I have tested the following code:
Spoiler :
Code:
local iDeltaSeconds = 1

local x = os.clock()
local n = 0
while os.clock() < x + iDeltaSeconds do
    n = n + 1
    --------------------
    local pPlayer = Players[0];
    local pUnits = pPlayer:GetUnits();
    local pPlot
    for ii, pUnit in pUnits:Members() do
        pPlot = Map.GetPlot(pUnit:GetX(), pUnit:GetY())
    end
    --------------------
end
print("n: " .. n)

When I let this test run several times the ouput looks like this:
Spoiler :
lua-performance-test-1-png.498553

So the number n of iteration steps within one second can vary, but the maximum is about 370.000 steps.

In my second test I wondered, how much performance it would save, if I declared some of the variables outside of the while loop:
Spoiler :
Code:
local iDeltaSeconds = 1

local x = os.clock()
local n = 0
local pPlayer = Players[0];

local pUnits = pPlayer:GetUnits();
local pPlot

while os.clock() < x + iDeltaSeconds do
    n = n + 1
    --------------------
    for ii, pUnit in pUnits:Members() do
        pPlot = Map.GetPlot(pUnit:GetX(), pUnit:GetY())
    end
    --------------------
end
print("n: " .. n)

In this case Firetuner can execute about 460.000 steps in one second, which is 25% more than 370.000 steps. So I conclude from this two tests that declaring variables within a loop can cause much more performance cost.


I will do further tests and try to collect more informations about how to save performance in Lua. Your help is appreciated, if you have your own suggestions.
 

Attachments

  • Lua Performance Test 1.PNG
    Lua Performance Test 1.PNG
    28.6 KB · Views: 420
Last edited:
See:
https://forums.civfanatics.com/threads/optimizing-your-lua-code-for-speed.463488/

In your example, you can try to also localize functions outside the loop:
Code:
local GetPlot = Map.GetPlot

Note that civ6 lua is faster than civ5 lua, but for pathfinding it's still a bit slow IMO, I've postponed the implementation of some advanced features in my W.I.P. until we get access to the source code, because of the slow down caused by pathfinding in late game on large maps.
 
Hey, that thread is really nice!
After looking at Pazyryk's testing code I wonder how it possible to use os.clock() for time differences below 1 second. In my tests os.clock() was only ably to count full seconds.
Another thing I want to mention is that Pazyryk takes the average of all computing times in his measurement series. However, I think the measurement outliers should be completely ignored, because sometimes the game can be lagging or needs to be revived from an idle mode, which can cause big measure differences.
Still the results in his thread are very helpful. Thanks for sharing!

Note that civ6 lua is faster than civ5 lua, but for pathfinding it's still a bit slow IMO, I've postponed the implementation of some advanced features in my W.I.P. until we get access to the source code, because of the slow down caused by pathfinding in late game on large maps.

Maybe you are right, but it could be still helpful for finding short paths e.g. if you want to tell the AI how to get to a nearby city. You could also try to precompute important routes and set stages.
Is there any topic for Lua overriding the AI behaviour? I would like to share my thoughts on that. :)
 
try
Code:
Automation.GetTime()

There is no dedicated thread for controlling AI using Lua, even if we had a few exchanges with @Siesta Guru in various threads on that subject, feel free to open one.
 

Thank you! This gives me the seconds with a high precision.
I guess Automation.GetTime() is a Lua function that can only be used in Civ6?

There is no dedicated thread for controlling AI using Lua, even if we had a few exchanges with @Siesta Guru in various threads on that subject, feel free to open one.

So I have created a thread now. I hope it is in the right sub-forum: https://forums.civfanatics.com/threads/lua-ai-control.633786/
 
Yes, it's one of the methods added for the game, I need to add the Automation table to the list of available Lua objects BTW.

And thanks for the thread, I'll follow it.
 
Back
Top Bottom