word on the street is that there are no constants in Lua like there are in C because there is in fact no pre-processing going on
that makes it probably a tradeoff between readable code and efficient code, since i also hear that global variables in Lua are looked up in some sort of table everytime they're accessed
the question is this: is the difference actually going to matter if i define a bunch of stuff in love.load (TILE_FLOOR = 0, TILE_WALL = 1, TILE_DOOR = 2, etc etc etc) versus using inscrutable numbers throughout my code
global constants in the name of efficiency
- tentus
- Inner party member
- Posts: 1060
- Joined: Sun Oct 31, 2010 7:56 pm
- Location: Appalachia
- Contact:
Re: global constants in the name of efficiency
The difference will be that one will be legible in a week, and the other won't.
Lua is dang fast, looking up global variables is not going to be your bottleneck, and it's not worth worrying about performance until you do have a significant problem anyhow. Define clearly named variables now and you'll be glad that you did later.
Lua is dang fast, looking up global variables is not going to be your bottleneck, and it's not worth worrying about performance until you do have a significant problem anyhow. Define clearly named variables now and you'll be glad that you did later.
Kurosuke needs beta testers
- Robin
- The Omniscient
- Posts: 6506
- Joined: Fri Feb 20, 2009 4:29 pm
- Location: The Netherlands
- Contact:
Re: global constants in the name of efficiency
Globals before magic numbers any time!
You might also want to consider using strings ("floor", "wall", "door") if it is applicable. That way, you have descriptive names without global lookups.
You might also want to consider using strings ("floor", "wall", "door") if it is applicable. That way, you have descriptive names without global lookups.
Help us help you: attach a .love.
Re: global constants in the name of efficiency
Yup. The global foo is _G['foo'] (or _ENV['foo'] in Lua 5.2).Benamas wrote:i also hear that global variables in Lua are looked up in some sort of table
You can use locals (e.g. local TILE_WALL = 1) which are implemented via array indexes rather than hash lookups.Benamas wrote:is the difference actually going to matter if i define a bunch of stuff in love.load (TILE_FLOOR = 0, TILE_WALL = 1, TILE_DOOR = 2, etc etc etc) versus using inscrutable numbers throughout my code
But I would focus more on writing correct code and forget about small efficiencies in this case.
- kikito
- Inner party member
- Posts: 3153
- Joined: Sat Oct 03, 2009 5:22 pm
- Location: Madrid, Spain
- Contact:
Re: global constants in the name of efficiency
Ok some facts. From less important to more important:
In a regular program, the "parts that matter" vary. Here are some common examples (this is not a complete nor exhaustive list):
- Variables defined with local are fastest to access than global variables. They are only available within the scope where they are defined. That scope can be a file.
- For a function, it is cheaper to access a parameter than it is to access a global variable
- On the other hand, invoking a function with parameters takes more than invoking it with no parameters (the parameters have to be "piled up").
- Most of the time, this doesn't matter.
In a regular program, the "parts that matter" vary. Here are some common examples (this is not a complete nor exhaustive list):
- Loops. The most loops you have, the slower your program will be. Especially if you have nested loops.
- Repeated calculations. Especially if they take too long to take.
- Access to disk/external systems (network, slow APIs, like writing to an ImageData).
- Doing too many things.
When I write def I mean function.
Re: global constants in the name of efficiency
Like robin said, it's usually better to use stings instead of globals - something like:
Lua checks strings very quickly because it just compares their reference in memory.
Constant strings usually make your code more legible/maintainable too.
The major bottlenecks in Lua from my experience are memory allocation and misusing tables.
For example:
Creating loads of tables each frame is not very good for performance either.
vs:
Code: Select all
if tile == "wall" then
Constant strings usually make your code more legible/maintainable too.
The major bottlenecks in Lua from my experience are memory allocation and misusing tables.
For example:
Code: Select all
sz = sz .. " string" -- allocates a new string and deferences another
Yes, probably true, although another useful thing about locals is that they often make your code shorter/easier to read:Trying to make a program faster by using locals instead of globals, or viceversa, is like like trying to make a car faster by painting it with a lighter paint
Code: Select all
love.graphics.print("This text is not black", 100, 100)
love.graphics.setColor(255,0,0)
love.graphics.print("This text is red", 100, 200)
Code: Select all
local lg = love.graphics
lg.print("This text is not black", 100, 100)
lg.setColor(255,0,0)
lg.print("This text is red", 100, 200)
Re: global constants in the name of efficiency
When you lookup a variable stored in the global table, lua uses it's internal interned string format to perform the lookup. As mentioned before, TILE_GRASS is really just sugar syntax for _G["TILE_GRASS"]. Normally, this is really fast because of the interning that goes on, which means the strings are compared via reference, and all new strings created are first checked against an internal table to see if the string already exists so that the existing reference can be reused. This makes table lookup O(1) amortized, meaning for all intents and purposes, it requires no additional time regardless of the size of the table over the life of the program.
Essentially, using named constants are already efficient.
As a side trick, you can set the named constants to the same string as their name. That way, you can live in both worlds, i.e. using regular named constants everywhere it doesn't matter, but using the string representation if it has to happen in a tightly optimized inner loop.
Here's a freebie that does what I'm talking about:
Essentially, using named constants are already efficient.
As a side trick, you can set the named constants to the same string as their name. That way, you can live in both worlds, i.e. using regular named constants everywhere it doesn't matter, but using the string representation if it has to happen in a tightly optimized inner loop.
Here's a freebie that does what I'm talking about:
Code: Select all
function constantify(...)
for i = 1, select('#', ...) do
local S = select(i, ...)
_G[S] = S
end
end
constantify( "APPLE", "BANANA", "CARROT" )
assert( APPLE == "APPLE" )
Re: global constants in the name of efficiency
This thread puts me at ease. I think I'll worry more about scope than efficiency now when deciding to declare a local variable.
Who is online
Users browsing this forum: No registered users and 7 guests