Data Realms Fan Forums http://45.55.195.193/ |
|
Faster Lua http://45.55.195.193/viewtopic.php?f=73&t=18060 |
Page 1 of 1 |
Author: | Kyred [ Mon Mar 08, 2010 12:11 pm ] |
Post subject: | Faster Lua |
Believe it or not, the way you write your code can have an impact on its performance in game. Usually, refining your algorithm(s) can reduce lots of Lua lag in CC. But sometimes this isn't enough. If you want to know how to squeeze every ounce of performance out of CC's Lua, read this short performance tips guide: http://lua-users.org/wiki/OptimisationCodingTips I'll point out some things that are pertinent to CC: Localize Heavily Referenced Globals Local variables in Lua are actually much faster than using global variables. The difference in speed is moot when if are only reference/change a global on a few times per update. However, if use globals inside loops, you'll get better performance if you store it to a local first. For example: Code: //Example A: //The variable MY_GLOBAL gets referenced 30 times per update. for i = 1,15,1 do MY_GLOBAL = i + MY_GLOBAL; end //Example B: local my_local = MY_GLOBAL; for i = 1,15,1 do my_local = i + my_local; end MY_GLOBAL = my_local In the examples above, example B only references MY_GLOBAL 2 times per execution, while in example A MY_GLOBAL is referenced 30 times. This makes example B 15x faster per execution compared to example A. The difference in speed per loop iteration may seem small, but it adds up when you have ~100 updates per second and 15 iterations per update. Use Multiplication Over Direct Division On Variables This one may seem a little bit outrageous, but Lua actually handles scalar multiplication on variables faster than division. For example, this: Code: 0.5*x Code: x/2 Also, a side note. When squaring a variable, its a bit faster to do x*x than x^2. Tables Use then when you can! Lua was built on tables, and its creators have optimized the ever-loving-shit out of them. You can put anything in a Lua table, even functions. When iterating through an unsorted table (which is typically what we deal with), use the pairs() operation whenever you can, over doing the iteration yourself. e.g. Code: for i,v in pairs(My_Table) do end If possible, it is generally faster to place elements in a table yourself using t[1+#t] rather than the table.insert() function. That's all I found in this guide. If I find anymore helpful information, I'll post it here. Update: 3/16/2010 Removing If/elseif Blocks Long lines of if and elseif blocks can sometimes bog your code down. In C/C++, an operator know as the "switch statement" was created to remove these clunky if/elseif blocks. However, Lua does not have a switch operator. But fear not! We can use Lua tables to efficiently emulate a switch statement. Code: function Update(self) local class = self.ClassName; if class == "AHuman" then --check 1 print(1); --block 1 elseif class == "ACrab" then --check 2 print(2); --block 2 elseif class == "HDFirearm" then --check 3 print(3); --block 3 elseif class == "TDExplosive" then --check 4 print(4); --block 4 end end This is a situation I see done in CC Lua every now and then. Here, we want the behavior of Update(self) to be depended on the ClassName of self. Using if/elseif blocks here works well, but the speed of the codes execution is dependent upon ClassName. Allow me to explain: Lets say ClassName is AHuman. This will cause only check 1 to be ran and block 1 to execute. We'll call this the "minimal case", because the least amount of code is executed in this situation. Now suppose our self's ClassName is HDFirearm. When Update is called, checks 1, 2, and 3 are ran, along with w/e is in block 3. So the amount of checks ran, is directly dependent on the ClassName of self. Of course, each check doesn't not require all that much processing power to execute. But when you have 20 if/elseif blocks in the center of a large script, these tiny checks make a difference. But through the use of Lua tables, you can completely eliminate checks all together and skip straight to executing blocks. Here's how: Code: function Create(self) self.switch = { ["AHuman"] = function () return 1 end, --block 1 ["ACrab"] = function () return 2 end, --block 2 ["HDFirearm"] = function () return 3 end, --block 3 ["TDExplosive"] = function () return 4 end --block 4 }; end function Update(self) local blockOfCode = self.switch[self.ClassName]; --returns a function. print( blockOfCode() ); --blockOfCode is a function, so we use () to execute it. end Now look at where the blocks have moved. They are now functions packed within table switch. So now, if self.ClassName is HDFirearm, then the table element with the index of "HDFirearm" is executed. Not only do you eliminate the use of if/elseif checks, but you also get to take advantage of the fast speed of Lua tables. |
Author: | Geti [ Mon Mar 08, 2010 12:50 pm ] |
Post subject: | Re: Faster Lua |
You would love reading through gems http://www.lua.org/gems/ Theres a whole chapter on optimisation. |
Author: | ScifiSpirit [ Sat Mar 13, 2010 2:04 am ] |
Post subject: | Re: Faster Lua |
Good to know. Even though I already read the "Lua Performance Tips", I didn't know about constant folding or that about multiplication. Anyway, I always fold them myself as well as I can. Seems a bit weird to me that X * (1/3) would be faster than X/3. Like totally counter-intuitive. 2 operations vs 1. And why doesn't the Lua compiler do a little bit of optimization in this case then? It doesn't sound too expensive, but I'm no compiler expert either. More practical examples relating to CC would be good too. |
Author: | Geti [ Sat Mar 13, 2010 3:28 am ] |
Post subject: | Re: Faster Lua |
ScifiSpirit wrote: Seems a bit weird to me that X * (1/3) would be faster than X/3. |
Author: | 411570N3 [ Sat Mar 13, 2010 3:34 am ] |
Post subject: | Re: Faster Lua |
So with recurring decimals you should probably just put as many decimal places as you need. Three to five is generally enough. |
Author: | ScifiSpirit [ Sat Mar 13, 2010 4:06 am ] |
Post subject: | Re: Faster Lua |
Geti wrote: ScifiSpirit wrote: Seems a bit weird to me that X * (1/3) would be faster than X/3. Yes, that was my point, however: http://lua-users.org/wiki/OptimisationCodingTips wrote: Constant folding: x * (1/3) is just as fast as x * 0.33333333333333333 and is generally faster than x/3 on most CPUs |
Author: | Grif [ Sat Mar 13, 2010 4:33 am ] |
Post subject: | Re: Faster Lua |
More relevant info could be gathered by running some tests on engine functions, and what are the most 'expensive' CC functions to use. |
Author: | Geti [ Sat Mar 13, 2010 6:11 am ] |
Post subject: | Re: Faster Lua |
ScifiSpirit wrote: however: Grif wrote: More relevant info could be gathered by running some tests on engine functions, and what are the most 'expensive' CC functions to use. |
Author: | Kyred [ Tue Mar 16, 2010 7:45 pm ] |
Post subject: | Re: Faster Lua |
I've updated my original post above to cover how use Lua tables to remove clunky if/elseif blocks of code. Enjoy |
Page 1 of 1 | All times are UTC [ DST ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |