View Single Post
05-08-17, 12:39 PM   #14
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
Originally Posted by Kkthnx View Post
I'd love to see more info on this. I have learned that is it is faster.
I'm not saying you did, but it's important not to take my quote out of context. I referred to this code sample, specifically. The call to getfenv() will take "much" longer than what you gained from upvaluing _G. _G = _G is better, in that case. Still very pointless.
Originally Posted by lightspark View Post
The only reason why I do local _G = getfenv(0) is my paranoia o_O

I've seen addons that do some weird manipulations w/ environments, so _G may end up being something else, and a check like _G == getfenv(0) will return false.
I mean, sure you can be careful, but there is such a thing as being too careful to the point of it just being foolish. "No offence". If addons are reassigning the global _G, at that point they're practically malware.


People need to understand what kind of gains we are talking about here. Some results were presented in one of the threads Ketho linked. I'd like to provide some more.

I tested the following cases using debugprofilestop(), which is very precise.

Over a hundred thousand iterations, calling UnitAura without any upvalues takes around 52 milliseconds.
Code:
for i = 1, 1e5 do
   local a = UnitAura("player", 1)
end
Doing the same with an upvalued UnitAura takes just under 51 ms.
Code:
local UnitAura = UnitAura
for i = 1, 1e5 do
   local a = UnitAura("player", 1)
end

As for assigning values, we're upping the iteration count to one million for increased accuracy. Upvaluing without using _G takes 15.5 ms.
Code:
for i = 1, 1e6 do
   local a = UnitAura
end
Upvaluing using _G, but without first having upvalued _G it self takes 26 ms, which is significantly slower. There's never any reason to do this thinking it's faster. (that's not the net loss I was talking about, though)
Code:
for i = 1, 1e6 do
   local a = _G.UnitAura
end
Doing the same with an upvalued _G is... actually still slower, for some reason. 15.7 ms. When I tested on PTR last night it was slightly faster. Possibly related to size of _G? Though I would've thought doing a global lookup would be affect by the size of _G in the same way.
Code:
local _G = _G
for i = 1, 1e6 do
   local a = _G.UnitAura
end
This is what I was referring to. Upvaluing _G to upvalue a single value through that is a net loss due to having perform a global lookup to get _G, and then a table lookup in _G to get UnitAura, as opposed to just doing a global lookup for UnitAura. This took 26 ms. Of course, the gain should be greater the more values you're upvaluing, though the above seems to imply the opposite... I'm not sure if there is some underlying caching going on that's skewing the results.
Code:
for i = 1, 1e6 do
   local _G = _G
   local a = _G.UnitAura
end
For reference, replaing _G with getfenv(0) in the above code puts the result at 123 ms.

Do with this info as you will.
Here is the exact test suite I'm using. Feel free to try to produce your own results.
Code:
local t = debugprofilestop

local ct = t()

for i = 1, 1e6 do
   local _G = getfenv(0)
   local a = _G.UnitAura
end

ct = t() - ct

print(format("Execution time: %s ms.", ct))
__________________
Grab your sword and fight the Horde!
  Reply With Quote