View Single Post
08-26-13, 09:11 PM   #23
kurapica.igas
A Chromatic Dragonspawn
Join Date: Aug 2011
Posts: 152
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