• Speed Analysis of pairs and ipairs
    43 replies, posted
[QUOTE=The-Stone;19612031]Garry disabled media-tags for images.[/QUOTE] Why? I prefer not seeing a 1920x1080 picture when I don't want to.
[code]> function foo() print("a") return 5 end for i=1,foo() do end a >[/code] the last index expression is only run once [editline]06:48AM[/editline] [QUOTE=NullPoint;19611376][QUOTE=grea$emonkey;19611309]It makes sense. I mean, ipairs needs to return an iterator function in addition to everything else.[/QUOTE]So does pairs, It just return next as the iterator function.[/QUOTE] they're using different iterator functions. I guess ipairs's is just badly optimized. there is one reason why you should use ipairs btw: pairs is not guaranteed to return the integer indexes in order if you don't believe me, check the manual. it makes no direct mention. it's not even really implied [editline]06:53AM[/editline] [code]] return ipairs({}) function: 02D76090 ] return ipairs({}) function: 02D76090 ] return ipairs({}) function: 02D76090 ] return pairs({}) function: 02D760A8 ] return next function: 02D75F40 [/code] pairs isn't even using next (directly), interesting... might be a trampoline or stub inbetween also, pairs and ipairs seem to use a fixed function, not a closure or something.
I applaud the OP for taking benchmarking into his own hands however I would totally google something like this before doing it myself (unless I were pretty bored). [url]http://trac.caspring.org/wiki/LuaPerformance[/url] The page contains a bunch of ways to optimize and get the best benchmarks... sort of trivial stuff at times although the localization stuff I would certainly agree with. If you ctrl+F ipairs, you'll see his tests prove what you're saying; that ipairs is indeed slower than pairs for larger tables (over 100 indexes).
interesting read, xciv
[QUOTE=haza55;19617730]Why? I prefer not seeing a 1920x1080 picture when I don't want to.[/QUOTE] Just use [img_thumb] tags. Like so: [img_thumb]http://facepunchstudios.com/facepunch.gif[/img_thumb]
[quote="http://trac.caspring.org/wiki/LuaPerformance"]TEST 8: functions as param for other functions Code1: [lua] local func1 = function(a,b,func) return func(a+b) end for i=1,1000000 do local x = func1(1,2,function(a) return a*2 end) end [/lua] Code2: [lua] local func1 = function(a,b,func) return func(a+b) end local func2 = function(a) return a*2 end for i=1,1000000 do local x = func1(1,2,func2) end [/lua] Results: defined in function param: 3.890 (1144%) defined as local: 0.344 (100%) Conclusion: REALLY, LOCALIZE YOUR FUNCTIONS ALWAYS BEFORE SENDING THEM INTO ANOTHER FUNCTION!!![/quote] Well, that [i]is[/i] interesting. [editline]01:35PM[/editline] Also, to say it yet again, but this time in big letters [highlight]PLEASE DO A SPEED ANALYSIS OF LOW-SIZED TABLES IE ONES THAT ARE 1 TO 200[/highlight] thank you.
1 to 100 table size. 10 samples at table size increments of 1. [img]http://img214.imageshack.us/img214/1166/100movavg.png[/img] [img]http://img62.imageshack.us/img62/6084/100linear.png[/img] [highlight]I have also found that using Garry's C++ interfaces, it is about 5 times slower than pairs. Use the lua functions, not Garry's when dealing with table loops in C++,[/highlight]
Thanks - you've debunked a widely spread myth.
[QUOTE=Lexic;19625138] [quote]TEST 8: functions as param for other functions Code1: [LIST=1] [*]local func1 = function(a,b,func) [*] return func(a+b) [*]end [*]for i=1,1000000 do [*] local x = func1(1,2,function(a) return a*2 end) [*]end [/LIST] local func1 = function(a,b,func) return func(a+b) end for i=1,1000000 do local x = func1(1,2,function(a) return a*2 end) end Code2: [LIST=1] [*]local func1 = function(a,b,func) [*] return func(a+b) [*]end [*]local func2 = function(a) [*] return a*2 [*]end [*]for i=1,1000000 do [*] local x = func1(1,2,func2) [*]end [/LIST] local func1 = function(a,b,func) return func(a+b) end local func2 = function(a) return a*2 end for i=1,1000000 do local x = func1(1,2,func2) end Results: defined in function param: 3.890 (1144%) defined as local: 0.344 (100%) Conclusion: REALLY, LOCALIZE YOUR FUNCTIONS ALWAYS BEFORE SENDING THEM INTO ANOTHER FUNCTION!!![/quote]Well, that [I]is[/I] interesting.[/QUOTE] What's going on is actually that in code1 he's creating a new closiure every time in the foor loop, it's a different operation to 'localize' your variables to make it faster. All you're doing here is making sure you don't generate closiures when you don't have to [editline]07:55PM[/editline] [QUOTE=TomyLobo;19622192][code]> function foo() print("a") return 5 end for i=1,foo() do end a >[/code]the last index expression is only run once[/QUOTE] I'm not sure what you're trying to imply here. You're doing nothing 5 times. [quote]pairs isn't even using next (directly), interesting... might be a trampoline or stub inbetween also, pairs and ipairs seem to use a fixed function, not a closure or something.[/quote]next is what's called a stateless iterator. Instead of creating a closiure every time you generate the iterator it always returns the same iterator function but is given the current state of the iterator, with next the state information is the table it's iterating on and the previous index. One of the optimizations it suggests is doing [lua]local sin = math.sin for i=1, 1000 do print(sin(i)) end[/lua] instead of always using math.sin. This is the obvious step for many uses of the function as it makes the number of index operations more constant. If you're only using the function 4 or 5 times you're probably ok leaving it out, it may not be worth the extra space required on the stack. The analysis used there tends towards speed optimization and not memory. With the indexing the array as opposed to unpacking it, I'd say that unpack is better practise for readability reasons alone. In test 4 he's using math.max for only 2 parameters, this is misleading since max is meant to be used for an arbitrary number of parameters. Test 5 surprises me, however I have suspicions about his claim since he's doing 'if y==nil', which is an extra comparison operation and isn't strictly speaking equivalent since 'or' allows false or nil. Test 6: x*x is an obvious one, since the power operation is defined for any size power. Test 7: of course x%y is faster than math.fmod(x, y), you're indexing the math table and performing a function call. I'm suspicious about some of this guy's claims.
"I'm not sure what you're trying to imply here. You're doing nothing 5 times." my point exactly. someone else said one should cache the last index to speed things up can't find the post to quote though. might have been the article too, I can't remember
sorry to necro this thread but i cannot see the images and a particularly interesting site, [url]http://trac.caspring.org/wiki/LuaPerformance[/url] has vanished. Is there a more recent refresh of this data?
[QUOTE=skypickle;48047861]sorry to necro this thread but i cannot see the images and a particularly interesting site, [url]http://trac.caspring.org/wiki/LuaPerformance[/url] has vanished. Is there a more recent refresh of this data?[/QUOTE] [url]http://web.archive.org/web/20120117012056/http://trac.caspring.org/wiki/LuaPerformance[/url]
Sorry, you need to Log In to post a reply to this thread.