ESOUI

ESOUI (https://www.esoui.com/forums/index.php)
-   Lua/XML Help (https://www.esoui.com/forums/forumdisplay.php?f=175)
-   -   LUA Performance questions (https://www.esoui.com/forums/showthread.php?t=1893)

lyravega 07/03/14 02:38 AM

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

Sasky 07/03/14 02:59 AM

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)

zgrssd 07/03/14 03:19 AM

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)

Seerah 07/03/14 01:14 PM

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.

lyravega 07/03/14 01:18 PM

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?

zgrssd 07/03/14 03:42 PM

Quote:

Originally Posted by lyravega (Post 10121)
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.

Sasky 07/03/14 04:27 PM

Quote:

Originally Posted by lyravega (Post 10121)
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.

zgrssd 07/04/14 02:26 AM

Quote:

Originally Posted by Sasky (Post 10127)
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

lyravega 07/04/14 11:58 PM

Quote:

Originally Posted by Seerah (Post 10120)
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?

merlight 07/05/14 11:38 AM

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)

Seerah 07/05/14 12:07 PM

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

lyravega 07/05/14 12:23 PM

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".

Seerah 07/05/14 12:58 PM

I'm not quite sure what you mean by "difference" other than scoping.


All times are GMT -6. The time now is 01:23 AM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2014 - 2022 MMOUI