Page 3 of 4
Re: Lua Performance Tips
Posted: Fri Aug 12, 2011 4:43 pm
by Xgoff
T-Bone wrote:Is this true for love functions as well? Should you like do
and so on? I already do that with some functions, but only when I want to change them.
i'll usually just use something like
not necessarily for optimization, but mainly because 'love.graphics' gets really annoying to type after a while. however, localizing is probably the easiest optimization you can do (one that can possibly
increase readability), but it usually doesn't pay off as much unless you have a massive chain of table lookups or something. there's also the problem of having only 200 locals per function (for standard lua, but this might also apply to luajit as well), and sometimes you need some of those locals for other purposes like upvalues
ivan wrote:The biggest performance drop in Lua that I've noticed is from creating unnecessary tables (for example in a loop) that get destroyed right away.
i remember reading somewhere that table creation is actually quite expensive, even more expensive than creating closures. collection can be expensive since lua doesn't have a generational gc, so creating lots of temporary garbage (coughvectorscough) can be nasty. 5.2 apparently will have a generational gc but they never got feedback on it which... either means it will be removed or undocumented, probably
Re: Lua Performance Tips
Posted: Fri Aug 12, 2011 5:37 pm
by benloran
ivan wrote:
This is an extra assignment which is not present in the "localize_method_no" test.
Well, the point of test02 is to test whether it's worth localizing a method within the body of the loop (in the case that you can't localize it outside of that scope). If I move the localization out of the loop, then it's just a repeat of test01. To make it more fair, I guess I could put a throwaway assignment inside the loop in localize_method_no.
ivan wrote:
- Strangely, custom unpack function is slower than localized unpack.
I'm not that suprised since a custom unpack function would probably have to make more operations to the stack than the regular unpack. "unpack_custom" needs to start a function scope, look up values, push them on the stack, etc.
I guess I figured that unpack itself would need to do those things, too. I have no idea how unpack works under the hood.
ivan wrote:
- Do not use math.max, math.min. Use conditionals instead.
math.max can work with a variable number of arguments so I assume that's why it's slower in your test.
That's a good point. I think I'll add tests that compare a variable number of arguments as well.
ivan wrote:
Test 8 probably also does an extra assignment (to a temp variable which is referenced to the "anonymous" function)
A more 'fair' test for funcparam_localized might be:
Code: Select all
local func1 = function(a,b,func) return func(a+b) end
local start = getTime()
for n=1,cycles do
local func2 = function(a) return a*2 end
local x = func1(1,2,func2)
end
I agree, I'll change that.
Thanks for the feedback!
Re: Lua Performance Tips
Posted: Fri Aug 12, 2011 8:35 pm
by Robin
benloran wrote:I guess I figured that unpack itself would need to do those things, too. I have no idea how unpack works under the hood.
IIRC, unpack is implemented in C, so that would have the advantage of not needing to be interpreted. Lua's fast, but it's not machine code.
Re: Lua Performance Tips
Posted: Fri Aug 12, 2011 8:56 pm
by benloran
benloran wrote:ivan wrote:
ivan wrote:
Test 8 probably also does an extra assignment (to a temp variable which is referenced to the "anonymous" function)
A more 'fair' test for funcparam_localized might be:
Code: Select all
local func1 = function(a,b,func) return func(a+b) end
local start = getTime()
for n=1,cycles do
local func2 = function(a) return a*2 end
local x = func1(1,2,func2)
end
I agree, I'll change that.
Actually, I take it back. The original intent of test 8 (I believe... I copied this from the LuaPerformance site) was to show that it's better to localize an anonymous function outside of the loop than to just write an anonymous function inside the function call.
Robin wrote:
IIRC, unpack is implemented in C, so that would have the advantage of not needing to be interpreted. Lua's fast, but it's not machine code.
That makes sense. I suspected something like that, but the same example on that LuaPerformance site shows the custom unpack as being much faster than Lua's unpack. That's what threw me.
Re: Lua Performance Tips
Posted: Fri Aug 12, 2011 9:18 pm
by Robin
benloran wrote:Actually, I take it back. The original intent of test 8 (I believe... I copied this from the LuaPerformance site) was to show that it's better to localize an anonymous function outside of the loop than to just write an anonymous function inside the function call.
Yeah, every time a
function statement/expression is executed, a new closure is created.
Re: Lua Performance Tips
Posted: Sat Aug 13, 2011 3:49 am
by Xgoff
benloran wrote:Robin wrote:
IIRC, unpack is implemented in C, so that would have the advantage of not needing to be interpreted. Lua's fast, but it's not machine code.
That makes sense. I suspected something like that, but the same example on that LuaPerformance site shows the custom unpack as being much faster than Lua's unpack. That's what threw me.
the lua implementation of unpack is faster because... it's not actually the same thing as the builtin unpack
the c unpack has to loop through the provided table to get everything, while the lua implementation just uses a fixed set of direct table accesses; if you only need a certain number of values it will of course be cheaper to do it in lua, but if you need one capable of an arbitrary number of returns then your only choice is unpack. the lua <-> c overhead isn't insignificant either. however, a proper unpack implemented entirely in lua
might be faster than the c version if you're using luajit
benloran wrote:Actually, I take it back. The original intent of test 8 (I believe... I copied this from the LuaPerformance site) was to show that it's better to localize an anonymous function outside of the loop than to just write an anonymous function inside the function call.
a nice thing 5.2 does is interning closures, if it detects that a function has the exact same definition and upvalues as another, it'll reuse the existing one instead of creating a new one. for example:
Code: Select all
-- in 5.1, 100 closures would be created; in 5.2 only 1 is
local x
for _ = 1, 100 do
(function () return x end)()
end
it'll still be slower than defining the function outside of the loop/function/whereever, but not by a whole lot. on the other hand it's a lot slower in 5.1
Re: Lua Performance Tips
Posted: Sat Aug 13, 2011 2:06 pm
by tsturzl
Best advice I can give you for code optimization is do it once you're done, do it only in area's its needed, don't over do it, if you don't NEED it don't DO it. Though this advice conflicts heavily with the gamers mindset, where they buy quad-core processors and dual GPUs just to get better FPS in WoW, it doesn't really help you all that much. Seriously, optimization prematurely can kill your project. Optimization once your done, can just add bugs. If you don't NEED it don't DO it.
Re: Lua Performance Tips
Posted: Tue Aug 30, 2011 2:08 pm
by miko
Roland_Yonaba wrote:T-Bone wrote:Is this true for love functions as well?
Of course, it is... Just assume that love functions are packed in a global table. Assigning them to local function make them run faster.
unless you have compiled love against luajit - in this case creating more variables makes things slower.
Roland_Yonaba wrote:
Anyway, I am pretty sure that this is unecessary, cause Löve engine is fast enough. That would be superfluous...
Agree. And if you really want your code faster, use luajit version of love and don't mess with the source code. But then, 90% of the time spent is probably on SDL side, not on Lua side.
Re: Lua Performance Tips
Posted: Tue Aug 30, 2011 2:36 pm
by GijsB
vrld,
when i did some changes to my code so it would get faster it was a diffrency of 0.1 seconds
per frame
Re: Lua Performance Tips
Posted: Tue Aug 30, 2011 3:58 pm
by slime
miko wrote:Roland_Yonaba wrote:T-Bone wrote:Is this true for love functions as well?
Of course, it is... Just assume that love functions are packed in a global table. Assigning them to local function make them run faster.
unless you have compiled love against luajit - in this case creating more variables makes things slower.
Incorrect. The
only time localizing variables will hurt performance in LuaJIT is when localizing a function/variable in a FFI C library namespace directly.
This only applies when you are using the LuaJIT FFI! localizing anything else will help performance!
Performance notice: the JIT compiler specializes to the identity of namespace objects and to the strings used to index it. This effectively turns function cdata objects into constants. It's not useful and actually counter-productive to explicitly cache these function objects, e.g. local strlen = ffi.C.strlen. OTOH it is useful to cache the namespace itself, e.g. local C = ffi.C.