Quantcast About add-ons optimization - Page 2 - WoWInterface
Thread Tools Display Modes
08-26-13, 09:51 AM   #21
Rainrider
A Scalebane Royal Guard
AddOn Author - Click to view addons
Join Date: Nov 2008
Posts: 438
That's an interesting one, but is it really worth it? You add everything from _G you use in your addon to the addon namespace, even if you only access it once. An upvalue is still faster than the non-global environment and you loose the ability to access _G directly. Or am I wrong about it?
  Reply With Quote
08-26-13, 03:35 PM   #22
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,603
That looks like a giant cluster**** and I would not recommend doing anything like it. If you need functions from one of your addon's files in another, just put them in the namespace table and call them as methods.

Also, that's not really relevant to this thread. If you want to discuss using custom function environments, please take that discussion to its own thread.
__________________
Author/maintainer of Grid, PhanxChat, oUF_Phanx, and many more.
Troubleshoot an addonTurn any code into an addonMore addon resources
Need help with your code? Post all of your actual code! Attach or paste your files.
Please don’t PM me about addon bugs or code questions. Post a comment or forum thread instead!
  Reply With Quote
08-26-13, 09:11 PM   #23
kurapica.igas
A Black Drake
Join Date: Aug 2011
Posts: 89
This is used to keep your variables not pollute the _G, and gain some code flexibility.Also, the up-value is not as quick as you think.

Here is a test, a() function contains a long calculation, and after it, there are three call types :

1. Define function in the global, call the global function directly.
2. Define up-values, the use the up-values to "speed up" the calculation.
3. Use the standalone environment, do the calculation.

Lua Code:
  1. do
  2.     function a()
  3.         local sum = 0
  4.         for i = 1, 100000 do
  5.             sum = sum + i
  6.         end
  7.     end
  8.  
  9.     oclock = os.clock
  10.  
  11.     do
  12.         -- Normal calls
  13.         function callA()
  14.             collectgarbage()
  15.  
  16.             local startTime = oclock()
  17.  
  18.             for i = 1, 10000 do
  19.                 a()
  20.             end
  21.  
  22.             local finsih = oclock()
  23.  
  24.             print("Normal cost ", finsih - startTime)
  25.         end
  26.  
  27.         callA()
  28.     end
  29.  
  30.     do
  31.         -- so la, loclock are up-value
  32.         local la = a
  33.         local loclock = oclock
  34.  
  35.         function callA()
  36.             collectgarbage()
  37.             local startTime = loclock()
  38.  
  39.             for i = 1, 10000 do
  40.                 la()
  41.             end
  42.  
  43.             local finsih = loclock()
  44.  
  45.             print("Up-value cost ", finsih - startTime)
  46.         end
  47.  
  48.         callA()
  49.     end
  50.  
  51.     do
  52.         local addon = {}
  53.  
  54.         if not getmetatable(addon) then
  55.             setmetatable(addon, {
  56.             __index = function(self,  key)
  57.                 -- keep vars in the _G to the addon to reduce the access cost
  58.                 local v = _G[key]
  59.                 if v ~= nil then
  60.                     rawset(self, key, v)
  61.                     return rawget(self, key)
  62.                 end
  63.             end,
  64.  
  65.             __metatable = true,
  66.             })
  67.         end
  68.  
  69.         setfenv(1, addon)
  70.  
  71.         -- Make sure metatable operations won't happen again when call callA
  72.         a = a
  73.         oclock = oclock
  74.  
  75.         -- so a, oclock are global in the environment, not up-value
  76.         function callA()
  77.             collectgarbage()
  78.             local startTime = oclock()
  79.  
  80.             for i = 1, 10000 do
  81.                 a()
  82.             end
  83.  
  84.             local finsih = oclock()
  85.            
  86.             print("Standalone environment cost ", finsih - startTime)
  87.         end
  88.  
  89.         callA()
  90.     end
  91. end

The result may not be exactly because there are too many things should cost the cpu in the same time, but you can see a lot in it, I run these code three times in lua 5.1.2 on mac shell:

Normal cost 16.129601
Up-value cost 16.357202
Standalone environment cost 16.308925
Normal cost 16.197299
Up-value cost 16.478886
Standalone environment cost 16.390823
Normal cost 16.203371
Up-value cost 16.468056
Standalone environment cost 16.404645
So the up-value part is the slowest.

In an addon, you don't need access all things in the _G, only what you need is saved to your addon, and if you want access something once, you always can do it like :

print(_G.CAT_FORM)

Just access if from _G table, you won't save the CAT_FORM in your addon.

Last edited by kurapica.igas : 08-27-13 at 12:05 AM.
  Reply With Quote
08-26-13, 11:11 PM   #24
kurapica.igas
A Black Drake
Join Date: Aug 2011
Posts: 89
Oh, one more thing, about the memory usage, the up-values cost much more if you use the local vars in many functions in your add-on, Here is a little test :

Lua Code:
  1. do
  2.     clear = function() collectgarbage() return collectgarbage("count") end
  3.  
  4.     for i = 1, 10 do
  5.         _G["a"..i] = function() end
  6.     end
  7.  
  8.     memStep0 = clear()
  9.  
  10.     do
  11.         local a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 = a1, a2, a3, a4, a5, a6, a7, a8, a9, a10
  12.  
  13.         for i = 1, 100 do
  14.             _G["A"..i] = function()
  15.                 a1() a2() a3() a4() a5() a6() a7() a8() a9() a10()
  16.             end
  17.  
  18.             _G["A"..i]()
  19.         end
  20.     end
  21.  
  22.     memStep1 = clear()
  23.  
  24.     do
  25.         local addon = {}
  26.         addon._Addon = addon  -- the addon itself
  27.  
  28.         if not getmetatable(addon) then
  29.             setmetatable(addon, {
  30.             __index = function(self,  key)
  31.                 -- keep vars in the _G to the addon to reduce the access cost
  32.                 local v = _G[key]
  33.                 if v ~= nil then
  34.                     rawset(self, key, v)
  35.                     return rawget(self, key)
  36.                 end
  37.             end,
  38.  
  39.             __metatable = true,
  40.             })
  41.         end
  42.  
  43.         setfenv(1, addon)
  44.  
  45.         for i = 1, 100 do
  46.             _Addon["A"..i] = function()
  47.                 a1() a2() a3() a4() a5() a6() a7() a8() a9() a10()
  48.             end
  49.  
  50.             _Addon["A"..i]()
  51.         end
  52.     end
  53.  
  54.     memStep2 = clear()
  55.  
  56.     print("Cost for up-values", memStep1 - memStep0)
  57.     print("Cost for standalone environment", memStep2 - memStep1)
  58. end

So, here is the result:

Cost for up-values 22.275390625
Cost for standalone environment 9.9453125
  Reply With Quote
08-26-13, 11:42 PM   #25
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 1,727
Originally Posted by Phanx View Post
Originally Posted by Malsomnus View Post
Phanx: Sorry, what I meant to say was not that I don't understand the statement, but that I don't understand the reasoning behind it, which appears counter-intuitive to me.
If we take your first and second examples, what do you gain by moving the variable into the loop? It seems like you just define 4 variables instead of just 1, which means more CPU time spent on creating the variable and more work for the GC.
You're creating 4 string values and performing 4 variable assignments either way. It doesn't matter whether you're overwriting an existing variable or not, so you should use scoping appropriately, and keep your code clean.
Explaining The Reason:
The point of keeping variables in their relevant scope is akin to only allocating memory when you need to use it and proper cleanup when you don't in other languages. All this is done behind the scenes with Lua's garbage collector, but it's still a good practice to follow nonetheless. These so-called "good programming practices" make it easy and simple to program reliable code regardless of which language you're using.




The code posted by Rainrider and Phanx are both correct, although the situations of the variables in question by each are completely different.
__________________
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote
08-27-13, 04:15 AM   #26
Malsomnus
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Apr 2013
Posts: 203
Originally Posted by SDPhantom View Post
Explaining The Reason:
The point of keeping variables in their relevant scope is akin to only allocating memory when you need to use it and proper cleanup when you don't in other languages. All this is done behind the scenes with Lua's garbage collector, but it's still a good practice to follow nonetheless. These so-called "good programming practices" make it easy and simple to program reliable code regardless of which language you're using.

The code posted by Rainrider and Phanx are both correct, although the situations of the variables in question by each are completely different.
The only reason I was going on about it was because in my testing, merely defining a single variable in the local scope of an OnUpdate function slowed my game's performance to a crawl. Moving that variable outside that scope and reusing it immediately solved the problem.
While it's obvious that, code-wise, a variable should be defined in the smallest scope possible, I think that that is not a tip that belongs in a discussion about optimization
__________________
SanityCheck - If you've ever said the words "Sorry, I forgot" then you need this add-on.

Remember, every time you post a comment on an add-on, a kitten gets its wings!
  Reply With Quote
08-27-13, 04:28 AM   #27
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,272
So it is worth to upvalue globals now or not?
  Reply With Quote
08-27-13, 09:49 AM   #28
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
Originally Posted by Malsomnus View Post
The only reason I was going on about it was because in my testing, merely defining a single variable in the local scope of an OnUpdate function slowed my game's performance to a crawl. Moving that variable outside that scope and reusing it immediately solved the problem.
Can you paste the code of this test?
__________________
Grab your sword and fight the Horde!
  Reply With Quote
08-27-13, 04:40 PM   #29
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,603
Originally Posted by Resike View Post
So it is worth to upvalue globals now or not?
There is no blanket answer to that question. If you're accessing a global in an OnUpdate script, CLEU handler, or other code path that runs frequently (especially in combat) then yes, you should upvalue it.

If you're accessing the global in response to the user checking a box in your options panel, or in response to an event like PLAYER_LOGIN or PLAYER_REGEN_DISABLED that doesn't fire very often, then while you will technically see a speed improvement by upvaluing it, in practical terms there is no value in doing so, so I'd recommend you keep your code tidy and not clutter it up with a bunch of practically useless upvalues.
__________________
Author/maintainer of Grid, PhanxChat, oUF_Phanx, and many more.
Troubleshoot an addonTurn any code into an addonMore addon resources
Need help with your code? Post all of your actual code! Attach or paste your files.
Please don’t PM me about addon bugs or code questions. Post a comment or forum thread instead!
  Reply With Quote
08-27-13, 04:41 PM   #30
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,603
Originally Posted by Malsomnus View Post
The only reason I was going on about it was because in my testing, merely defining a single variable in the local scope of an OnUpdate function slowed my game's performance to a crawl. Moving that variable outside that scope and reusing it immediately solved the problem.
Was that variable's value a table or function? If so, that is your problem, and it has nothing to do with where the variable is defined.

But, without seeing the actual code in question, it's really pointless to talk about it.
__________________
Author/maintainer of Grid, PhanxChat, oUF_Phanx, and many more.
Troubleshoot an addonTurn any code into an addonMore addon resources
Need help with your code? Post all of your actual code! Attach or paste your files.
Please don’t PM me about addon bugs or code questions. Post a comment or forum thread instead!
  Reply With Quote
08-27-13, 08:30 PM   #31
kurapica.igas
A Black Drake
Join Date: Aug 2011
Posts: 89
Well, if you need a var in the OnUpdate or something happened frequently, I suggest you may try the coroutine. Also a test example :

1. First part is using a local var 'sum' to contains the sum result. And then we call it 10000 times.
2. Second part is using a coroutine to keep everything, we also can it 10000 times.

Lua Code:
  1. do
  2.     oclock = os.clock
  3.  
  4.     do
  5.         local sum = 0
  6.  
  7.         function Sum(num)
  8.             for i = 1, num do
  9.                 sum = sum + i
  10.             end
  11.         end
  12.  
  13.         function callSum()
  14.             collectgarbage()
  15.             local startTime = oclock()
  16.  
  17.             for i = 1, 10000 do
  18.                 Sum(i)
  19.             end
  20.  
  21.             local finsih = oclock()
  22.  
  23.             print("Result is", sum)
  24.             print("Up-value cost ", finsih - startTime)
  25.         end
  26.  
  27.         callSum()
  28.     end
  29.  
  30.     print("----------------------------")
  31.  
  32.     do
  33.         create = coroutine.create
  34.         resume = coroutine.resume
  35.         running = coroutine.running
  36.         status = coroutine.status
  37.         wrap = coroutine.wrap
  38.         yield = coroutine.yield
  39.  
  40.         function Sum(num)
  41.             local sum = 0
  42.  
  43.             while num do
  44.                 for i = 1, num do
  45.                     sum = sum + i
  46.                 end
  47.                 num = yield()
  48.             end
  49.  
  50.             print("Result is", sum)
  51.         end
  52.  
  53.         function callSum()
  54.             collectgarbage()
  55.             local startTime = oclock()
  56.             local thread = create(Sum)
  57.  
  58.             for i = 1, 10000 do
  59.                 resume(thread, i)
  60.             end
  61.  
  62.             resume(thread)
  63.  
  64.             local finsih = oclock()
  65.  
  66.             print("Thread cost ", finsih - startTime)
  67.         end
  68.  
  69.         callSum()
  70.     end
  71. end

The result is :

Result is 166716670000
Up-value cost 1.406231
----------------------------
Result is 166716670000
Thread cost 0.853961
Normally, like an OnUpdate handler, you can do it like :

Lua Code:
  1. local thread = create(function(...)
  2.     local var1, var2
  3.  
  4.     while true do
  5.         -- Handle your code
  6.         yield()
  7.     end
  8. end)
  9.  
  10. frame:SetScript("OnUpdate", function(self)
  11.     resume(thread)
  12. end)

So, when your frame is visible, the thread will be called again and again, when not, the thread will be stop until the frame is shown again.

But, if your handle code is tiny, just use upvalue, in the previous example, if you change the code
Lua Code:
  1. for i = 1, num do
  2.     sum = sum + i
  3. end
To
Lua Code:
  1. sum = sum + num

The result should be

Result is 50005000
Up-value cost 0.0021880000000003
----------------------------
Result is 50005000
Thread cost 0.0052459999999996
So, the choose is based on your code, and the coroutine is more complex than the upvalue, if you do it wrong, it may crash your game.
  Reply With Quote
08-27-13, 11:19 PM   #32
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,603
Please stop derailing this "basic tips for optimization" thread with your posts about coroutines and custom function environments. If you want to post tutorials on those subjects, please do it a new thread.
__________________
Author/maintainer of Grid, PhanxChat, oUF_Phanx, and many more.
Troubleshoot an addonTurn any code into an addonMore addon resources
Need help with your code? Post all of your actual code! Attach or paste your files.
Please don’t PM me about addon bugs or code questions. Post a comment or forum thread instead!
  Reply With Quote
08-28-13, 01:08 AM   #33
ballagarba
A Fallenroot Satyr
 
ballagarba's Avatar
Join Date: Mar 2009
Posts: 22
I find his stuff very interesting to be honest.

1. Don't do premature optimization.
2. Don't sacrifice readability for negligible optimizations.

That being said, here's a PDF on performance tips for Lua written by its lead architect.

http://www.lua.org/gems/sample.pdf

Last edited by ballagarba : 08-28-13 at 01:10 AM.
  Reply With Quote
08-28-13, 04:32 AM   #34
kurapica.igas
A Black Drake
Join Date: Aug 2011
Posts: 89
Originally Posted by ballagarba View Post
I find his stuff very interesting to be honest.

1. Don't do premature optimization.
2. Don't sacrifice readability for negligible optimizations.

That being said, here's a PDF on performance tips for Lua written by its lead architect.

http://www.lua.org/gems/sample.pdf
Thanks for the book.

I also take back the word 'The upvalue is the slowest', I'm confused about the result too, redo the test several times today, only 1 time the upvalue is slower than others, the diff between them is little.

I prefer the custom environment just because after some time, the custom environment will store all things that the addon needed, from the point, the custom environment table will be stable compares to the _G.
  Reply With Quote
08-28-13, 10:18 AM   #35
Malsomnus
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Apr 2013
Posts: 203
Originally Posted by ballagarba View Post
1. Don't do premature optimization.
2. Don't sacrifice readability for negligible optimizations.
Yep. Every programmer should tattoo this somewhere, just to be on the safe side
__________________
SanityCheck - If you've ever said the words "Sorry, I forgot" then you need this add-on.

Remember, every time you post a comment on an add-on, a kitten gets its wings!
  Reply With Quote
08-29-13, 03:49 AM   #36
Kagura
A Fallenroot Satyr
Join Date: Nov 2008
Posts: 21
On the subject to declaring variables to their most confining scope next should be noted:
Lua Code:
  1. local a
  2. for i=1, 5 do
  3.     a = i
  4. end
Code:
-- Compiles into

main <test.lua:0,0> (7 instructions, 28 bytes at 0x80049128)
0+ params, 5 slots, 0 upvalues, 5 locals, 2 constants, 0 functions
        1       [3]     LOADK           1 -1    ; 1
        2       [3]     LOADK           2 -2    ; 5
        3       [3]     LOADK           3 -1    ; 1
        4       [3]     FORPREP         1 1     ; to 6
        5       [4]     MOVE            0 4
        6       [3]     FORLOOP         1 -2    ; to 5
        7       [5]     RETURN          0 1
]]

Lua Code:
  1. for i=1, 5 do
  2.     local a
  3.     a = i
  4. end

Code:
-- Compiles into

main <test.lua:0,0> (8 instructions, 32 bytes at 0x80049128)
0+ params, 5 slots, 0 upvalues, 5 locals, 2 constants, 0 functions
        1       [2]     LOADK           0 -1    ; 1
        2       [2]     LOADK           1 -2    ; 5
        3       [2]     LOADK           2 -1    ; 1
        4       [2]     FORPREP         0 2     ; to 7
        5       [3]     LOADNIL         4 4
        6       [4]     MOVE            4 3
        7       [2]     FORLOOP         0 -3    ; to 5
        8       [5]     RETURN          0 1
]]
and

Lua Code:
  1. for i=1, 5 do
  2.     local a = i
  3. end

Code:
-- Compiles into

main <test.lua:0,0> (7 instructions, 28 bytes at 0x80049128)
0+ params, 5 slots, 0 upvalues, 5 locals, 2 constants, 0 functions
        1       [2]     LOADK           0 -1    ; 1
        2       [2]     LOADK           1 -2    ; 5
        3       [2]     LOADK           2 -1    ; 1
        4       [2]     FORPREP         0 1     ; to 6
        5       [3]     MOVE            4 3
        6       [2]     FORLOOP         0 -2    ; to 5
        7       [4]     RETURN          0 1
As you can guess, the second is a bit slower, but it should also be noted that the gain from this is only going to be noticable for large amount of variable declarations.

While doing a large amount of variable declarations, next should also be noted (I'll leave the compiled versions out since I don't want to pollute the thread):

Lua Code:
  1. function UnitAura(unitId, index)
  2. end
  3.  
  4. local startTime, endTime
  5. startTime = os.clock()
  6. for j = 1, 1000000 do
  7.     local name, rank, icon, count, dispelType, duration, expires, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff, value1, value2, value3
  8.     for i = 1, 40 do
  9.         name, rank, icon, count, dispelType, duration, expires, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff, value1, value2, value3 = UnitAura("player", i)
  10.     end
  11. end
  12. endTime = os.clock()
  13.  
  14. print(endTime-startTime)
  15.  
  16. startTime = os.clock()
  17. for j = 1, 1000000 do
  18.     for i = 1, 40 do
  19.         local name, rank, icon, count, dispelType, duration, expires, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff, value1, value2, value3 = UnitAura("player", i)
  20.     end
  21. end
  22. endTime = os.clock()
  23.  
  24. print(endTime-startTime)
  25.  
  26. startTime = os.clock()
  27. for j = 1, 1000000 do
  28.     for i = 1, 40 do
  29.         local name, rank, icon, count, dispelType, duration, expires, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff, value1, value2, value3
  30.         name, rank, icon, count, dispelType, duration, expires, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff, value1, value2, value3 = UnitAura("player", i)
  31.     end
  32. end
  33. endTime = os.clock()
  34.  
  35. print(endTime-startTime)
  36.  
  37. --- Results
  38. $ lua test.lua
  39. 5.859
  40. 2.562
  41. 6.375

If you really want to optimize your addon, you need to look at compiled code and understand how function calls/lua stack works.
  Reply With Quote
08-29-13, 03:52 PM   #37
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 1,727
This is still deviating from the point Phanx and I were making. Phanx is stating as a general rule that locals should stay in the tightest scope possible. My posts state that like most rules, there are some exceptions over the argument whether locals should stay in or out of loops.

Among these is the point that when dealing with constants or CPU-intensive calculations that don't change in the loop, you're best left upvaluing them instead of having the loop reinitialize the variable with the same value multiple times.
__________________
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote
08-29-13, 05:38 PM   #38
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,603
Yep, you guys are definitely missing the point. This is a thread about simple, general tips that don't require a lot of coding experience or deep knowledge of how Lua works internally -- it's not meant to cover every possible scenario, and it's not meant to delve into complicated schemes for extreme optimization of every single CPU cycle. I'm tired of asking, but if you want to provide lengthy benchmarking results and tutorials covering every possible exception to the rule, or extreme micro-optimization, please start your own threads for that stuff.
__________________
Author/maintainer of Grid, PhanxChat, oUF_Phanx, and many more.
Troubleshoot an addonTurn any code into an addonMore addon resources
Need help with your code? Post all of your actual code! Attach or paste your files.
Please don’t PM me about addon bugs or code questions. Post a comment or forum thread instead!
  Reply With Quote
09-04-13, 09:21 AM   #39
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,272
Originally Posted by Kagura View Post
Lua Code:
  1. function UnitAura(unitId, index)
  2. end
  3.  
  4. local startTime, endTime
  5. startTime = os.clock()
  6. for j = 1, 1000000 do
  7.     local name, rank, icon, count, dispelType, duration, expires, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff, value1, value2, value3
  8.     for i = 1, 40 do
  9.         name, rank, icon, count, dispelType, duration, expires, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff, value1, value2, value3 = UnitAura("player", i)
  10.     end
  11. end
  12. endTime = os.clock()
  13.  
  14. print(endTime-startTime)
  15.  
  16. startTime = os.clock()
  17. for j = 1, 1000000 do
  18.     for i = 1, 40 do
  19.         local name, rank, icon, count, dispelType, duration, expires, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff, value1, value2, value3 = UnitAura("player", i)
  20.     end
  21. end
  22. endTime = os.clock()
  23.  
  24. print(endTime-startTime)
  25.  
  26. startTime = os.clock()
  27. for j = 1, 1000000 do
  28.     for i = 1, 40 do
  29.         local name, rank, icon, count, dispelType, duration, expires, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff, value1, value2, value3
  30.         name, rank, icon, count, dispelType, duration, expires, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff, value1, value2, value3 = UnitAura("player", i)
  31.     end
  32. end
  33. endTime = os.clock()
  34.  
  35. print(endTime-startTime)
  36.  
  37. --- Results
  38. $ lua test.lua
  39. 5.859
  40. 2.562
  41. 6.375
As soon as you going to start to use thoose varliabes in the second version, it's going to be as slow as the third one. The extra time for the first version comes from the lookup time and not beacuse it's not in the tightest scope.
  Reply With Quote
09-05-13, 07:20 AM   #40
Kagura
A Fallenroot Satyr
Join Date: Nov 2008
Posts: 21
Originally Posted by Resike View Post
As soon as you going to start to use thoose varliabes in the second version, it's going to be as slow as the third one. The extra time for the first version comes from the lookup time and not beacuse it's not in the tightest scope.
Actually it won't be slower. But Phanx is right, I think the thread is derailing too much from "simple optimization" to getting every bit of performance you can possibly get.

p.s. If you are really curious, the test results with your suggestion is : here
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » About add-ons optimization

Thread Tools
Display Modes

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