Code Optimizing & Performance trics

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.
User avatar
Virox
Citizen
Posts: 64
Joined: Thu Jan 07, 2010 6:24 pm

Re: Code Optimizing & Performance trics

Post by Virox »

Some questions
If you have a loop running through a table.

Code: Select all

for i, item in pairs( itemtable ) do
   if condition = true then
      itemtable[i] = nil
   end
end
So this should make some items in the table nil.
- I heard the garbage collector picks them out and removes them from the table at some point? is this correct en when will this happen exactly?
- Is it possible to make this code more optimized/faster?
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Code Optimizing & Performance trics

Post by bartbes »

There is no way when this happens exactly unless you call the garbage collector explicitly, and even then you can only be sure it is collected afterwards, the GC just collects whenever it detects your program is not doing anything time-critical.

Optimization:

Code: Select all

for i, item in pairs( itemtable ) do
   itemtable[i] = condition and item
end
No clue if this works, but worth a shot.
User avatar
Virox
Citizen
Posts: 64
Joined: Thu Jan 07, 2010 6:24 pm

Re: Code Optimizing & Performance trics

Post by Virox »

bartbes wrote:There is no way when this happens exactly unless you call the garbage collector explicitly, and even then you can only be sure it is collected afterwards, the GC just collects whenever it detects your program is not doing anything time-critical.
so it's not like that the collector is run automaticly between every frame or after the loop is done?
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Code Optimizing & Performance trics

Post by bartbes »

No, LÖVE doesn't call it, and the GC has no predictable timing, though it would make sense if it collected during the sleep in the main loop. (or shortly before/after)
User avatar
Virox
Citizen
Posts: 64
Joined: Thu Jan 07, 2010 6:24 pm

Re: Code Optimizing & Performance trics

Post by Virox »

Does it make a difference when you draw something with coordinates existing out of integers or decimals(floating point numbers)?
Actually is it good to work constantly with decimals in general? or is it better to work with math.floor or math.ceiling? (although they are slow to...)

thank god that bartbes is a robot and can't get tired of my questions :P
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Code Optimizing & Performance trics

Post by bartbes »

Lua always uses the same type internally (double), so it shouldn't matter, and yes, math.floor and ceil are slow (but %1 is pretty fast).
Virox wrote:thank god that bartbes is a robot and can't get tired of my questions :P
I'm not a robot, I'm a machine, there's a difference. Oh, and I can get tired of your questions.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Code Optimizing & Performance trics

Post by kikito »

I've got a couple advices about optimization.

Avoid premature optimization. This one is not mine:
Donald Knut wrote:We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil
The best way of having a correct algorithm is:
  • Start with code as human-understandable as possible. In some occasions this will mean making your code slightly slower on the CPU, but if it makes your code easier to understand for the programmer, then it is the right way to go.
  • Then, if your code is fast enough (90% of the time it is), you have finished. You won. Go do another thing.
  • If it is too slow for your needs, *profile it*. Don't start making random "optimizations" here and there. Be methodical, and find the real bottlenecks.
  • When you have found where the real performance issue is, optimize that part only. This could render the code a little less understandable for humans. Add as many comments as necessary in order to compensate that.
This is also not mine.

I want to point out that I don't want to imply that optimized code is allways "more complex" than non-optimized code. Quite often it is just the opposite; the fastest solution is also the simplest to understand. Trying to achieve the most optimized code isn't about thinking about "details" (how can I initialize this variable faster? How can I increase this other faster?) but about the whole structure of your progam (do I really need to cycle over this bunch of elements? Can I save this to a variable instead of having to calculate it on every frame?)

Now, for some lua-specifics:
  • The __index metamethod invokation is quite fast (3 pointer indirections in C, if I remember correctly). Use it when you can, but remember: make your code human-understandable.
  • This is implementation-specific, but in general, ipairs(t) is a bit faster than pairs(t)
  • Tables with non-consecutive integers, or with 'gaps', are less efficient than tables without gaps (ipairs stops at the first gap, so you have to use pairs to parse them)
  • There's also the common idiom for the ternary operator. In other languages you have a ternary operator using ? and : :

Code: Select all

a = b > c ? 1 : 0
Since in LUA there are no ternary operators, you have to use if-elses to do the same thing:

Code: Select all

if(b>c) then
  a = 1
else
  a = 0
end
But there's actually a more efficient way of doing the same thing in lua using and-or :

Code: Select all

a = b > c and 1 or 0
This code does the same as the previous one, but it is faster. Since it is not very human-readable, add a comment:

Code: Select all

 -- if b > 0, then a=1. Else a = 0
a = b > c and 1 or 0
Also, this solution only works for small conditions, such as b>c. For more complex conditions, it is better that you use an if.
  • Another place for skipping ifs is in the default parameters of functions. If you have a function with an optional parameter, and you want it to be 1 by default, use 'or' like this:

Code: Select all

function foo(p1, p2) -- p2 is optional, default value of 1
  p2 = p2 or 1 -- if p2 is nil, this sets it to 1. Otherwise it leaves it untouched

When I write def I mean function.
User avatar
Jasoco
Inner party member
Posts: 3725
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Code Optimizing & Performance trics

Post by Jasoco »

bartbes wrote:Lua always uses the same type internally (double), so it shouldn't matter, and yes, math.floor and ceil are slow (but %1 is pretty fast).
Virox wrote:thank god that bartbes is a robot and can't get tired of my questions :P
I'm not a robot, I'm a machine, there's a difference. Oh, and I can get tired of your questions.
What does %1 do? Does it have anything to do with rounding like Floor and Ceil?

Because I know about wrapping variables with a % sign.

100 % 65 will be 45 because it wraps the 100 when it gets to 65 taking it back to 1 then continuing for the remainder. But does it do anything else? What are some math tricks Lua can do?
User avatar
TechnoCat
Inner party member
Posts: 1611
Joined: Thu Jul 30, 2009 12:31 am
Location: Denver, CO
Contact:

Re: Code Optimizing & Performance trics

Post by TechnoCat »

Jasoco wrote:What does %1 do? Does it have anything to do with rounding like Floor and Ceil?

Because I know about wrapping variables with a % sign.

100 % 65 will be 45 because it wraps the 100 when it gets to 65 taking it back to 1 then continuing for the remainder. But does it do anything else? What are some math tricks Lua can do?
http://en.wikipedia.org/wiki/Modulo_operator
http://www.lua.org/manual/5.1/manual.html#2.5.1
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 130 guests