when overhead matters: return tables, or multiple values?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
2_bit_encryption
Prole
Posts: 3
Joined: Tue Jan 19, 2016 9:18 pm

when overhead matters: return tables, or multiple values?

Post by 2_bit_encryption »

I can already tell this is an "it depends" question, but I have to ask it anyway.

I've been thinking about my lower level design of my game a lot from the beginning. I chose to implement all my methods that return x,y coordinates as:

Code: Select all

function whatever:get_location()
    return {self.x, self.y}
end
And then I have X globally defined as 1 and Y globally defined as 2, so I can easily pull out X or Y or use both. I like how this looks visually and it is pretty simple in my head. (I do the same thing with functions that return dimensions: return {self.width, self.height})

However, obviously get_location() functions are called LOTS of times per gametick on LOTS of different items. And each time, a table has to be created. So I'm making something on the order of thousands (millions? I honestly don't know) of tables per second just to return x,y pairs.

I'm not far enough to know if this will effect performance. I'm guessing it won't, not noticeably. But I can't help but think of it and ask people who might know more.

So how much overhead does simple table creation create? If I switch to multiple return values (i.e., say

Code: Select all

return self.x, self.y
) instead of

Code: Select all

return {self.x, self.y}
) am I really saving any time/cycles? Again, I'm sure I might be overthinking this, but I'm so curious that I have to know.

Thanks!

EDIT: and how could I forget to mention function overhead? By calling a get_location() function on tons of objects every frame, I'm incorporating function overhead and table generation at the same time, when I could just be doing object.xy to directly access the table. Is it worth eliminating all that function overhead for slightly less readable and more confusing code?
User avatar
rmcode
Party member
Posts: 454
Joined: Tue Jul 15, 2014 12:04 pm
Location: Germany
Contact:

Re: when overhead matters: return tables, or multiple values?

Post by rmcode »

I don't think there is any measurable difference between calling a function and accessing a reasonably sized table object.xy (if there is then I have never noticed). Personally I prefer a combination of local variables and public functions for my object's attributes ... I almost never store the values directly in the object's table.

As a rule of thumb you should try to produce as few throwaway tables as possible (just collectgarbage and watch your the gc when you use tables vs. when you use variables). Personally I think that multiple return values are a very beautiful feature of Lua and you should use them :D

As a general tip: Watch out not to over-optimize. It's good to think about your code, but don't fall in the trap of never writing a line of code because you overthink everything you do. Just write your feature / game / program and think about optimization when you actually hit bottlenecks. Also optimization should never be done without profiling. Just because something "should be" faster doesn't mean it actually is when you write it out.
bobbyjones
Party member
Posts: 730
Joined: Sat Apr 26, 2014 7:46 pm

Re: when overhead matters: return tables, or multiple values?

Post by bobbyjones »

Recently this has been a reoccurring discussion in #love. The best way to optimize vectors in lua. So far the best way is to use ffi and pool your vectors. It will decrease memory usage, make your math faster, reduce GC issues and is much more convenient than just returning x or y and even more convenient than returning {x,y}. But as rmcode said unless you are having issues or know that you will don't worry too much about it. Although I will say that it will come up if you are creating those tables in a inner loop thousands times a frame. I had this come up multiple times for me. For vectors I recommend using cpml's vec2. It's still being refactored so it may not be stable but i have used it and tested it. It doesn't pool the vectors but you probably would not need that.

CPML's Vec2: https://github.com/excessive/cpml/blob/ ... s/vec2.lua
User avatar
Kingdaro
Party member
Posts: 395
Joined: Sun Jul 18, 2010 3:08 am

Re: when overhead matters: return tables, or multiple values?

Post by Kingdaro »

As rmcode stated, you definitely shouldn't worry about optimizing a lot of the time, especially when you're working with one of the fastest scripting languages available, while it's run with the fastest interpreter / JIT compiler available for the language. Most of the time, unless your game is slowing down significantly, you should work however you're most comfortable.

A note, however, that common practice is to return multiple values, then assign blanks (underscores, '_') to whichever variables you don't need in a certain scope:

Code: Select all

local _, y = thing:getPosition()
local _, height = thing:getSize()
You can also use select(). It's more verbose, but looks visually clean:

Code: Select all

local y = select(2, thing:getPosition())
local height = select(2, thing:getSize())
Because, yes, creating a table for each return is a decent amount of overhead compared to using multiple returns. There's a good reason why there are multiple returns in the language at all. ;)
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 7 guests