Thread Tools Display Modes
07/03/14, 02:38 AM   #1
lyravega
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 93
LUA Performance questions

Hello all. How is it going? I have some questions, if someone can shed a light on them I'd greatly appreciate that.

My biggest question is, lets assume there is a function which refers to metatable (self) to get a variable. Assuming that it is going to be used more than once, we should always create a local in the function body, correct?

--more will follow

Last edited by lyravega : 07/03/14 at 02:47 AM.
  Reply With Quote
07/03/14, 02:59 AM   #2
Sasky
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 231
Could you post say an example in code of what you're talking about? I think I can figure out what you're talking about, but not entirely sure.

In general, I'd suggest worry about code legibility over optimization. If you do want to look at optimization, I'd suggest looking at:
http://lua-users.org/wiki/OptimisingUsingLocalVariables
(and other pages on that site)
  Reply With Quote
07/03/14, 03:19 AM   #3
zgrssd
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 280
As Sasky said, perfromce is indeed a secondary concern.
There is one reason a thousand times more important to prefer local variables:
Global in Lua is more global then any other language. The global namespaces is shared between your addons filles, all other addons and even Zenimax own code.

For example I am able to override GetDisplayName() (because it is global) and Zenimax own SavedVar code will use my overridden version. Don't use global unless you are really, REALLY certain what you are doing.

For tables keep in mind that you are copying only the reference. So both variables will still point to the same table (call by reference).
Note that there is a build in function for cloning tables:
ZO_DeepTableCopy(source, dest)

Last edited by zgrssd : 07/03/14 at 03:28 AM.
  Reply With Quote
07/03/14, 01:14 PM   #4
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 648
My guess on what the OP is asking is this: (Again, just a guess, as the OP wasn't very clear.)

Lua Code:
  1. function DoStuff()
  2.      if myTable.var == "something" then
  3.           OtherFunction(myTable.var)
  4.      elseif myTable.var == "somethingelse" then
  5.           NextFunction(myTable.var)
  6.      else
  7.           LastFunction(myTable.var)
  8.      end
  9. end

In the above pseudo-code, you are looking up the value of myTable.var 5 times. In this case, it would be more efficient to assign the value to a local variable and do this instead:
Lua Code:
  1. function DoStuff()
  2.      local var = myTable.var
  3.      if var == "something" then
  4.           OtherFunction(var)
  5.      elseif var == "somethingelse" then
  6.           NextFunction(var)
  7.      else
  8.           LastFunction(var)
  9.      end
  10. end

Granted, the gain is minimal unless this code is being executed at a high rate, such as for every OnUpdate or for an event that fires often.
  Reply With Quote
07/03/14, 01:18 PM   #5
lyravega
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 93
Performance is a primary concern for my code, as it is time critical. For example, a simple code, which is time critical (expected to finish 100 runs in a second at least):

Code:
for derp = 1, 100 do
x = y * z
end
vs

Code:
for derp = 1, 100 do
local y = y
local z = z
x = y * z
end
For this little stupid code above, since the variables are used only once, making a local variable "feels" like it slows the process down, as instead of just using these variables, it will have to make a local and assign those variables to these locals, taking the extra mile. However, I can see a performance benefit if a variable was used more than once.

A general question would be, is there a case that locals should be avoided?
  Reply With Quote
07/03/14, 03:42 PM   #6
zgrssd
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 280
Originally Posted by lyravega View Post
Performance is a primary concern for my code, as it is time critical. For example, a simple code, which is time critical (expected to finish 100 runs in a second at least)
A requirement of "X runs per second minimum" is flat out impossible. Regardless of environment and programming language. It just won't happen.

The CPU executes your code as fast as it can. Not a single cycle faster. Also currently Addons run in the UI thread. Wich means they are single threaded and your code running too long can hold up the UI thread (it was propably ZrMM that caused the delays on people entering the group).

If you ever have a "minimum amount of throughput per timeframe" requirement, your design is wrong.
  Reply With Quote
07/03/14, 04:27 PM   #7
Sasky
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 231
Originally Posted by lyravega View Post
Performance is a primary concern for my code, as it is time critical. For example, a simple code, which is time critical (expected to finish 100 runs in a second at least):

Code:
for derp = 1, 100 do
x = y * z
end
vs

Code:
for derp = 1, 100 do
local y = y
local z = z
x = y * z
end
For this little stupid code above, since the variables are used only once, making a local variable "feels" like it slows the process down, as instead of just using these variables, it will have to make a local and assign those variables to these locals, taking the extra mile. However, I can see a performance benefit if a variable was used more than once.

A general question would be, is there a case that locals should be avoided?
Actually, in that case where it's only used once, you don't get a time savings.

Setting up sample:
Warning: Spoiler

10 million iterations of this take about .5sec on my computer and the difference between the two is negligible. Successive runs will even flip which one is faster.

However, multiple access is where you do start to notice a difference (in 10 million runs).
Putting the "z = x*y" three times per loop, you get around 1.65s versus 0.94s

Where you get the savings is in lookups to the global table. When you only use the global once, you still have to look it up once to create the local variable.

Also, I can't stress this enough:
I had to go to millions of iterations to get a measurable difference.

If you find yourself needing this level of optimization, please 1) evaluate whether you really need to run that many operations that frequently and 2) use some profiling tools so you can see where you're eating up your time. Switching to local does squat if your main bottleneck is removing elements using table.remove() from the front of a table.

Last edited by Sasky : 07/03/14 at 05:46 PM.
  Reply With Quote
07/04/14, 02:26 AM   #8
zgrssd
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 280
Originally Posted by Sasky View Post
Also, I can't stress this enough:
I had to go to millions of iterations to get a measurable difference.

If you find yourself needing this level of optimization, please 1) evaluate whether you really need to run that many operations that frequently and 2) use some profiling tools so you can see where you're eating up your time. Switching to local does squat if your main bottleneck is removing elements using table.remove() from the front of a table.
I can only add one thing:
The 6 part performance rant
  Reply With Quote
07/04/14, 11:58 PM   #9
lyravega
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 93
Originally Posted by Seerah View Post
Granted, the gain is minimal unless this code is being executed at a high rate, such as for every OnUpdate or for an event that fires often.
Ding ding! This is my primary concern. I wasn't able to express myself very well. There still is a gain though, I hope.

Another question, how are the locals in the main body are treated as opposed to locals in the function body?

Last edited by lyravega : 07/05/14 at 12:23 AM.
  Reply With Quote
07/05/14, 11:38 AM   #10
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
A lua file is compiled as a function, which is then called. http://www.lua.org/manual/5.1/manual.html#pdf-loadfile (although ZOS stripped loadfile from the API, I assume their internal loading function does the same)
  Reply With Quote
07/05/14, 12:07 PM   #11
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 648
Here are some reading materials on scoping in Lua.

http://www.lua.org/pil/4.2.html
http://lua-users.org/wiki/ScopeTutorial
http://wowpedia.org/Lua_variable_scoping
  Reply With Quote
07/05/14, 12:23 PM   #12
lyravega
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 93
Thanks for the links Seerah, but my problem is not with scoping. I am just asking if there is a difference between lets say, "function locals" and "file locals".
  Reply With Quote
07/05/14, 12:58 PM   #13
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 648
I'm not quite sure what you mean by "difference" other than scoping.
  Reply With Quote

ESOUI » Developer Discussions » Lua/XML Help » LUA Performance questions


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off