Lua Performance Tips

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
benhumphreys
Prole
Posts: 31
Joined: Thu Sep 13, 2012 2:10 am

Lua Performance Tips

Post by benhumphreys »

I found this wiki page on Lua performance tips. Maybe it's something everyone knows about already, but some parts surprised me.
  • Anonymous functions as parameters were 10x slower
  • pairs and ipairs are twice as slow as regular for loops
  • table.insert was 7x slower than regular access
I guess this all applies to Löve Lua code too?

Are there any Löve-specific performance tips that people should know about?
User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Re: Lua Performance Tips

Post by Roland_Yonaba »

benhumphreys wrote: I guess this all applies to Löve Lua code too?
Yep, totally.
benhumphreys wrote: Are there any Löve-specific performance tips that people should know about?
I can redirect you to this thread, maybe you'll find a lot more inspiring tips.
User avatar
Boolsheet
Inner party member
Posts: 780
Joined: Wed Dec 29, 2010 4:57 am
Location: Switzerland

Re: Lua Performance Tips

Post by Boolsheet »

That link did indeed already come up a few times. :)
benhumphreys wrote:
  • Anonymous functions as parameters were 10x slower
However you define it in this context, all or none of the functions in Lua are anonymous. Wikipedia says all are considered anonymous.
Anyway, creating a new function for every call is slow. Creating the same function over and over is not smart. Why did they even use that code example?
benhumphreys wrote:
  • pairs and ipairs are twice as slow as regular for loops
The for iterators include function calls. A function call is generally a slow thing.
benhumphreys wrote:
  • table.insert was 7x slower than regular access
Besides it being a function, table.insert does more than just add a value to a index. It also reorders the table if the value is inserted in the middle of the sequence.

Hm, I'm not sure if there's something LÖVE-specific without going into premature optimizations. When you hit a bottleneck you most likely have to redesign parts.
Shallow indentations.
User avatar
Xgoff
Party member
Posts: 211
Joined: Fri Nov 19, 2010 4:20 am

Re: Lua Performance Tips

Post by Xgoff »

Boolsheet wrote:That link did indeed already come up a few times. :)
benhumphreys wrote:
  • Anonymous functions as parameters were 10x slower
However you define it in this context, all or none of the functions in Lua are anonymous. Wikipedia says all are considered anonymous.
Anyway, creating a new function for every call is slow. Creating the same function over and over is not smart. Why did they even use that code example?
i guess creating new functions like that is common for more functionalish stuff. also, sometimes you're pretty much forced to create a closure.

a good love performance tip is if it's a function whose name begins with 'new' then be really careful about how often you call it!
User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Re: Lua Performance Tips

Post by Roland_Yonaba »

Didn't want to make a new thread, then I just resurrected this old one.
Here is a benchmark chart for Lua and lots of other languages.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Lua Performance Tips

Post by kikito »

I just want to point out that creating functions is not necessarily that slow. At least, not as slow as it would seem.

While I was implementing my line-rendering algorithm I did a small performance test. I did two versions of the test with the same algorithm. The first version gradually built a table of coordinates, and then returned it for processing in a loop. The other version, accepted a callback, and applied the callback to each result pair as soon as it was available. The callback was being re-created on each test, not reused from one iteration to the next.

It turns out that the second version, even when creating a new function on each iteration, was faster than the "build an array of elements, return it and parse it with a loop" option. I was a bit surprised; I thought function building would be a bit slower. My conclusion was: function creation might not be super fast, but it's still better than some other stuff, like table creation (at least when loops are involved).
When I write def I mean function.
User avatar
dreadkillz
Party member
Posts: 223
Joined: Sun Mar 04, 2012 2:04 pm
Location: USA

Re: Lua Performance Tips

Post by dreadkillz »

I discovered that closures are cheap if the underlying operations per closure creation are more expensive than the creation of the closure. I have made this same update in my sweep and prune for raycasting. Before that, I used a table to store my state for the raycast iterator. Now I just create a closure for each iterator as it's pretty cheap compared to the operation of raycasting itself.

Just to add to that closures is a really nice feature for capturing states.
User avatar
Inny
Party member
Posts: 652
Joined: Fri Jan 30, 2009 3:41 am
Location: New York

Re: Lua Performance Tips

Post by Inny »

I had a big back and forth on reddit with someone about the performance of closures. In testing, he convinced me of how bad closures can get if you misuse them as part of any class-based object oriented system. It had to do with the size of the "objects" ballooning pretty big, and the garbage collector running way too frequently with nothing to show for its efforts. As I understand, this kind of thing is what the 5.2 optimizations around closures address (i.e. the self parameter gets shadowed, so all of the methods become identical).

This is the technique I'm talking of:

Code: Select all

function newFoo(...)
  local self = {...}
  function self:bar()
    -- something something
  end
  return self
end
I don't have the exact test handy, but it involved loading up the objects created with several hundreds of methods.

So, uh, don't do this. :P

Closures are still great for callbacks.
Post Reply

Who is online

Users browsing this forum: No registered users and 5 guests