Originally Posted by Kkthnx
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
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))