Thread Tools Display Modes
08-17-12, 06:23 PM   #1
Jarod24
A Theradrim Guardian
AddOn Author - Click to view addons
Join Date: Jul 2012
Posts: 66
local pointers of functions

So i've been looking though the blizzard files and i have come across stuff like this:


Code:
--this is from GameTime.lua

local date = date;
local format = format;
local GetCVarBool = GetCVarBool;
local CalendarGetDate = CalendarGetDate;
local max = max;
local tonumber = tonumber;
Does such re-declaring of global functions as "local" like this improve performance?

Its late and i'm sorry if this has been answered a thousand times before.
  Reply With Quote
08-17-12, 06:39 PM   #2
d87
A Chromatic Dragonspawn
 
d87's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2006
Posts: 163
Does such re-declaring of global functions as "local" like this improve performance?
yes, access to local variables is faster than to global ones.
  Reply With Quote
08-17-12, 06:41 PM   #3
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 793
If you call "time" in your file (and it is not declared) the game will look up _G environment and see if it exists there, i.e. it does a table lookup each global API call. On the other hand if you do "local time = time" now when you call time the reference is already "cached" locally to your file so that makes it faster since no table lookup is ever performed. Not 100% sure but pretty sure this is the explanation.
__________________
Profile: Curse | Wowhead
  Reply With Quote
08-17-12, 07:44 PM   #4
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
That's correct. Think of it like this: When you do a global lookup, it has to find the memory address where the value (function, string, whatever) is located - each time.

Code:
local variable_name = memory_address_of_value
No more lookups.
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.
  Reply With Quote
08-17-12, 08:19 PM   #5
nailertn
An Aku'mai Servant
Join Date: Oct 2008
Posts: 33
Code:
global_variable = 1

for i = 1, 1e8 do
	global_variable = global_variable + 1
end
On my PC this runs in 4.98 seconds.

Code:
local local_variable = 1

for i = 1, 1e8 do
	local_variable = local_variable + 1
end
And this in 0.96 seconds.

A very significant difference but I consider it clutter unless it's for something I use a lot, say for an OnUpdate or every CLEU / UNIT_AURA in a raid.
  Reply With Quote
08-17-12, 08:22 PM   #6
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
Something else declaring the function locally does is prevent any addons loaded after that from modifying its behavior. Whether or not that's a good thing sort of depends on the situation.
  Reply With Quote
08-18-12, 04:43 AM   #7
Jarod24
A Theradrim Guardian
AddOn Author - Click to view addons
Join Date: Jul 2012
Posts: 66
Thanks for the quick answer.

I'll go and optimize my addon now
  Reply With Quote
08-18-12, 05:59 AM   #8
Jarod24
A Theradrim Guardian
AddOn Author - Click to view addons
Join Date: Jul 2012
Posts: 66
Um. 2 more questions...

Things like string.len() and strlen() are as far as i know the same thing, but why do they both exist?

Is it just legacy from ealier Lua versions (pre 5.1) or are they maybe Blizzard implemented shortcuts/wrappers?


When it comes to referring to functions in tables.
Code:
--is this better?
local math_abs = math.abs;
local math_floor = math.floor;

--would just referring to 'math' itself be good enough?
local math = math;
Am i correct in thinking that using an math_abs approach would be better? In my head, that would refer directly to the function in question, saving you the _G lookup and then the math[] table-lookup aswell.

Last edited by Jarod24 : 08-18-12 at 06:17 AM.
  Reply With Quote
08-18-12, 06:25 AM   #9
Jarod24
A Theradrim Guardian
AddOn Author - Click to view addons
Join Date: Jul 2012
Posts: 66
hehe, nevermind. I figured it out on my own.

math is a simple table wrapper that holds all the functions related to math of corse.

math.abs() simply points to the function abs() etc.

The same goes for string.upper(), it points to strupper(). its all simple aliases.

(curses his object oriented mind)
  Reply With Quote
08-18-12, 08:29 AM   #10
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 793
math.abs will first lookup for math, then look up abs in math, two lookups.
local math_abs = math.abs will save you two lookups each time you call it in the long run :P
__________________
Profile: Curse | Wowhead
  Reply With Quote
08-18-12, 03:36 PM   #11
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,326
Originally Posted by semlar View Post
Something else declaring the function locally does is prevent any addons loaded after that from modifying its behavior. Whether or not that's a good thing sort of depends on the situation.
A local variable of any type isn't available for access outside the scope it's defined in. There are few exceptions such as a table who's pointer is stored in another variable too.





Originally Posted by Jarod24 View Post
hehe, nevermind. I figured it out on my own.

math is a simple table wrapper that holds all the functions related to math of corse.

math.abs() simply points to the function abs() etc.

The same goes for string.upper(), it points to strupper(). its all simple aliases.

(curses his object oriented mind)
Actually, the math and string tables along with table are function libraries that are stock in any Lua distribution. Blizzard just relinked them to different globals. Practically the same explanation, corrections only on a really minor detail, the global versions are the wrappers. There is a difference though in the trig functions (sin(), cos(), tan(), etc.) as the Lua ones found in the math table use Radians and the ones in the global namespace use Degrees.

If you're looking for easier ways to manipulate strings, all strings share the string table as their metatable. This means you can call these functions directly from a string and by using the obj:func() syntax, it'll pass the string itself as the first argument.

Example:
Code:
local str="some string";
print(str:upper());--	Prints "SOME STRING"
You can call these from a literal string too, but this requires some ingenuity.
Code:
print(("some string"):upper());--	Prints "SOME STRING"
Note parenthesis are used to theoretically convert the literal string into a value before the metatable can be accessed. If this isn't done, Lua will throw a syntax error.
__________________
WoWInterface AddOns
"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-18-12, 07:11 PM   #12
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by SDPhantom View Post
If you're looking for easier ways to manipulate strings, all strings share the string table as their metatable. This means you can call these functions directly from a string and by using the obj:func() syntax, it'll pass the string itself as the first argument.

Example:
Code:
local str="some string";
print(str:upper());--	Prints "SOME STRING"
You can do it that way, but it's even slower than strupper("some string") when strupper is a global lookup, and WAY slower than the same when strupper has been upvalued. See here for some recent benchmarking tests.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » local pointers of functions


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