Example: tourism industry

Lua Performance Tips

2 Lua Performance TipsRoberto IerusalimschyIn Lua, as in any other programming language, we should always follow the twomaxims of program optimization:Rule #1:Don t do #2:Don t do it yet.(for experts only)Those rules are particularly relevant when programming in Lua. Lua is famousfor its Performance , and it deserves its reputation among scripting , we all know that Performance is a key ingredient of program-ming. It is not by chance that problems with exponential timecomplexity arecalledintractable. A too late result is a useless result. So, every good program-mer should always balance the costs from spending resourcesto optimize a pieceof code against the gains of saving resources when running that first question regarding optimization a good programmeralways asks is: Does the program needs to be optimized?

x = x + math.sin(i) end return x end print(foo(10)) We can optimize it by declaring sin once, outside function foo : local sin = math.sin function foo (x) for i = 1, 1000000 do x = x + sin(i) end return x end print(foo(10)) This second code runs 30% faster than the original one. Although the Lua compiler is quite efc ient when compared wi th ...

Tags:

  Performance, Tips, Math, Lua performance tips

Information

Domain:

Source:

Link to this page:

Please notify us if you found a problem with this document:

Other abuse

Transcription of Lua Performance Tips

1 2 Lua Performance TipsRoberto IerusalimschyIn Lua, as in any other programming language, we should always follow the twomaxims of program optimization:Rule #1:Don t do #2:Don t do it yet.(for experts only)Those rules are particularly relevant when programming in Lua. Lua is famousfor its Performance , and it deserves its reputation among scripting , we all know that Performance is a key ingredient of program-ming. It is not by chance that problems with exponential timecomplexity arecalledintractable. A too late result is a useless result. So, every good program-mer should always balance the costs from spending resourcesto optimize a pieceof code against the gains of saving resources when running that first question regarding optimization a good programmeralways asks is: Does the program needs to be optimized?

2 If the answer is positive (but onlythen), the second question should be: Where? To answer both questions we need some instrumentation. We should nottry to optimize software without proper measurements. The difference betweenexperienced programmers and novices isnotthat experienced programmers arebetter at spotting where a program may be wasting its time: The difference isthat experienced programmers know they are not good at that few years ago, Noemi Rodriguez and I developed a prototype for a CORBAORB (Object Request Broker) in Lua, which later evolved intoOiL (Orb inLua).

3 As a first prototype, the implementation aimed at simplicity. To avoidCopyrightc 2008 by Roberto Ierusalimschy. Used by Lua Performance Tipsthe need for extra C libraries, the prototype serialized integers using a fewarithmetic operations to isolate each byte (conversion to base 256). It did notsupport floating-point values. Because CORBA handles strings as sequences ofcharacters, our ORB first converted Lua strings into a sequence (that is, a Luatable) of characters and then handled the result like any other we finished that first prototype, we compared its Performance againsta professional ORB implemented in C++.

4 We expected our ORB tobe somewhatslower, as it was implemented in Lua, but we were disappointed by how muchslower it was. At first, we just laid the blame on Lua. Later, wesuspectedthat the culprit could be all those operations needed to serialize each , we decided to run the program under a profiler. We used a very simpleprofiler, not unlike the one described in Chapter 23 ofProgramming in profiler results shocked us. Against our gut feelings, the serialization ofnumbers had no measurable impact on the Performance , among other reasonsbecause there were not that many numbers to serialize.

5 The serialization ofstrings, however, was responsible for a huge part of the total time. Practicallyevery CORBA message has several strings, even when we are notmanipulatingstrings explicitly: object references, method names, and some other internalvalues are all coded as strings. And the serialization of each string was anexpensive operation, because it needed to create a new table, fill it with eachindividual character, and then serialize the resulting sequence, which involvedserializing each character one by one. Once we reimplemented the serializationof strings as a special case (instead of using the generic code for sequences), wegot a respectable speed up.

6 With just a few extra lines of code, the performanceof your implementation was comparable to the C++ , we should always measure when optimizing a program for before, to know where to optimize. And measure after,to know whetherthe optimization actually improved our you decide that you really must optimize your Lua code, this text mayhelp you about how to optimize it, mainly by showing what is slow and what isfast in Lua. I will not discuss here general techniques for optimization, suchas better algorithms. Of course you should know and use thosetechniques,but there are several other places where you can learn them.

7 In this articleI will discuss only techniques that are particular to Lua. Along the article, I willconstantly measure the time and space Performance of small programs. Unlessstated otherwise, I do all measures on a Pentium IV GHz with 1 GB of mainmemory, running Ubuntu , Lua Frequently I give actual measures( , 7 seconds), but what is relevant is the relationship between differentmeasures. When I say that a program is X% times faster than another itmeans that it runs inX% less time. (A program 100% faster would take no timeto run.) When I say that a program is X% times slower than another I meanthat the other isX% faster.

8 (A program 50% slower means that it takes twicethe time.)1Of course our implementation was still slower, but not by an order of factsBefore running any code, Lua translates (precompiles) the source into an in-ternal format. This format is a sequence of instructions fora virtual machine,similar to machine code for a real CPU. This internal format is then interpretedby C code that is essentially awhileloop with a largeswitchinside, one case foreach you have already read somewhere that, since , Lua usesa register-based virtual machine. The registers of this virtual machine do notcorrespond to real registers in the CPU, because this correspondence would benot portable and quite limited in the number of registers available.

9 Instead,Lua uses a stack (implemented as an array plus some indices) to accommodateits registers. Each active function has anactivation record, which is a stackslice wherein the function stores its registers. So, each function has its ownregisters2. Each function may use up to 250 registers, because each instructionhas only 8 bits to refer to a that large number of registers, the Lua precompiler isable to store alllocal variables in registers. The result is that access to local variables is veryfast in Lua. For instance, ifaandbare local variables, a Lua statement likea = a + bgenerates one single instruction:ADD 0 0 1(assuming thataandbare in registers 0 and 1, respectively).

10 For comparison, if bothaandbwereglobals, the code for that addition would be like this:GETGLOBAL 0 0 ; aGETGLOBAL 1 1 ; bADD 0 0 1 SETGLOBAL 0 0 ; aSo, it is easy to justify one of the most important rules to improve the perfor-mance of Lua programs:use locals!If you need to squeeze Performance out of your program, thereare severalplaces where you can use locals besides the obvious ones. Forinstance, if youcall a function within a long loop, you can assign the function to a local instance, the codefor i = 1, 1000000 dolocal x = (i)endruns 30% slower than this one:local sin = i = 1, 1000000 dolocal x = sin(i)end2 This is similar to theregister windowsfound in some Lua Performance TipsAccess to external locals (that is, variables that are localto an enclosingfunction) is not as fast as access to local variables, but it is still faster thanaccess to globals.


Related search queries