[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto] ## [Tips] Optimization 101 Started by Danny Dec 02 2011 06:45 PM     8 votes
87 replies to this topic
[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#76

### Hendrix000007

[GLOBAL: userInfoPane.html]
Hendrix000007
• Contributor

• • 177 posts
• Corona SDK

@Rob Miracle

You are like a lexicon man thanx

[TOPIC: post.html]
#77

### roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
• Corona Geek

• • 7,640 posts
• Corona SDK

(Disclaimer: Verify this on your target platform before believing this.)

Current testing Results

• Simulator on Windows 7 PC - num ^ 0.5 = 40%+ faster
• iPad Air Gen 1 (iOS 8.02) - math.sqrt() = %21 faster

The Real Take Away

Test any optimization on your target machine before assuming it will work.

The Short Description Of This Tip (for the attention-challenged )

```local sqrt( num )
return num ^ 0.5
end```

may be  faster than:

```local mSqrt = math.sqrt
local sqrt( num )
return mSqrt( num )
end
```

The Long Description Of This Tip

I recently answered a math question which led me to calculate the Nth root of a number.  The equation for this is:

```local function( num, root )
return num ^ 1/root
end```

While there is nothing exciting about this, it suddenly occurred to me that this might be faster than the math.sqrt function for root == 2.

It is!  .... or is it?

On my windows test machine, num^0.5 is almost 40% faster than a localized math.sqrt() call.  However, on my iPad Air math.sqrt is 21% faster

Here is my test code:

```
local function round(val, n)
if (n) then
return math.floor( (val * 10^n) + 0.5) / (10^n)
else
return math.floor(val+0.5)
end
end

local function test1( num )
local mSqrt = math.sqrt
local startTime = system.getTimer()
local v
for i = 1, num do
v = mSqrt(i)
end
local endTime = system.getTimer()
local dt = (endTime-startTime)
print("math.sqrt x " .. num .. " == " .. dt .. " ms" )
return dt
end

local function test2( num )
local mSqrt = math.sqrt
local startTime = system.getTimer()
local v
for i = 1, num do
v = i^0.5
end
local endTime = system.getTimer()
local dt = (endTime-startTime)
print("M^0.5 x " .. num .. " == " .. dt .. " ms" )
return dt
end

local t1 = 0
local t2 = 0
t1 = t1 + test1(1000000)
t1 = t1 + test1(1000000)
t1 = t1 + test1(1000000)
t2 = t2 + test2(1000000)
t2 = t2 + test2(1000000)
t2 = t2 + test2(1000000)

if( t1 > t2 ) then
print(" M^0.5 is faster by " .. round( 1 - t2/t1,2 ) * 100 .. "%"  )
else
print(" math.sqrt is faster by " .. round( 1 - t1/t2,2 ) * 100 .. "%"  )
end
```

Edited by roaminggamer, 17 March 2015 - 12:23 PM.

[TOPIC: post.html]
#78

### StarCrunch

[GLOBAL: userInfoPane.html]
StarCrunch
• Contributor

• • 842 posts
• Corona SDK

@roaminggamer

On that same note, I've found multiplying by powers of 2, e.g. x * 2^power, quite a lot faster than bit.lshift() or math.ldexp() (with the localizations, of course) in the Windows simulator. On device, I don't know if I've done any tests. Likewise x^2 versus x * x (lookup local, invoke operator with constant, vs. lookup local, lookup "another" local, invoke operator).

On the subject of bitwise ops, where possible, I tend to favor the + and - operators over of bit.bor() and bit.band() / bit.bnot(). The % operator, on the other hand, still seemed pretty expensive vs. bit.band().

Any non-Windows numbers, or contrary results on Windows itself, would be much appreciated!

[TOPIC: post.html]
#79

### roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
• Corona Geek

• • 7,640 posts
• Corona SDK

For optimization geeks, I created an additional way to test the above (requires above code):

```

local function visualizeResults2( test1, test2, size, num, doPower )
local t1 = 0
local t2 = 0
size = size or 2
num = num or 100

local t1 = 0
local t2 = 0
local count = 1

local width  = round(display.contentWidth/size)
local height = round(display.contentHeight/size)

local yield = coroutine.yield

print("Running ", width * height * num * 2, " calculations." )
local lastTime = getTimer()
local timerID
local wrapped = coroutine.wrap(
function( event )
for i = 1, height do
for j = 1, width do
if( doPower ) then
t1 = test1( num, 10^(count-1) )
t2 = test2( num, 10^(count-1) )
else
t1 = test1( num, count )
t2 = test2( num, count )
end
local tmp = display.newRect( (j-1) * size, (i-1) * size,  size, size )
tmp.anchorX = 0
tmp.anchorY = 0
if( t1 > t2 ) then
--if( count%7 == 0 ) then
tmp:setFillColor(0,1,0)
else
tmp:setFillColor(1,0,0)
end
count = count + 1
--if( count%100 == 0 ) then yield() end
if( getTimer() - lastTime > 25 ) then
lastTime = getTimer()
yield()
end

end
end
print("DONE")
timerID = event.source
timer.cancel(timerID)
end )
timer.performWithDelay( 1, wrapped, 0 )

end

visualizeResults2( test1, test2, 8, 10000, true )
```

This produces a full page visualization of what numbers are faster one way or the other.  Interestingly for certain powers of 10, one method is faster than the other.

Note: I think  I have an error in the above code as it crashes at the end. oops!

[TOPIC: post.html]
#80

### Hendrix000007

[GLOBAL: userInfoPane.html]
Hendrix000007
• Contributor

• • 177 posts
• Corona SDK

@StarCrunch

Yes, it is actually a real handy little thing the do command

If there is a certain order you like to fire functions and blocks of code, you can put them in do blocks

and the way you show it here is really nice because the variables lives just as long as the do block is active

when it´s done executing, the scope is gone and all the local variables in the scope is released too

I use it quite often

[TOPIC: post.html]
#81

### Hendrix000007

[GLOBAL: userInfoPane.html]
Hendrix000007
• Contributor

• • 177 posts
• Corona SDK

Here´s a couple of functions I made to both check what´s actually going on inside the package.loaded table at runtime:

I make a global function in the mainfile:

```function printClasses()
print(k)
end
end
function deleteClass(class)
print("**** Removed class: " .. class, " ******")
end
end
```

If you run your code with theese functions inside you can look in the terminal and se all the modules/ classes loaded.

```require("MyModule")
```

This will be listed in the terminal window if you call:

```printClasses()
```

Now, let´s say that you want to clean up because the player has won or lost and he/ she is taken to a typical gameover page you can run the second function and remove the module completely, you just call the function from whereever you like in your code:

```deleteClass("MyModule")
```

The simulator will print out: **** Removed class: MyModule  ******

I use these functions alot

[TOPIC: post.html]
#82

### evanspro

[GLOBAL: userInfoPane.html]
evanspro
• Contributor

• • 186 posts
• Corona SDK

Thanks a lot Hendrix000007 ! It's gonna be very usefull to me [TOPIC: post.html]
#83

### noriega

[GLOBAL: userInfoPane.html]
noriega
• Observer

• • 25 posts
• Corona SDK

https://docs.coronalabs.com/guide/basics/optimization/index.html

I noticed the localizing parts refer to the main lua libraries (math, io, type),

1st question: Would this also prove useful to the corona sdk libraries.. such as if i was creating a lot of display.newText's in a file,  would be better or worse if I was to declare local dNewText = display.newText or would there be no noticeable difference?

2nd question: I am also assuming that all these core lua functions are ones I should be localize for optimization if I use them in my code.

On the bottom of the manual
http://www.lua.org/manual/5.1/

I am trying to find the find the line between optimization and over optimization.

[TOPIC: post.html]
#84

### roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
• Corona Geek

• • 7,640 posts
• Corona SDK

@noribl87,

1. Localization would make it faster, but not noticeably unless you did many.

2. Localization gives you the most speedup for functions where, the 'table lookup' is comparable to the execution time of the function.

(T below is a 'made up unit of time' for the examples just to show relative improvement)

Example 1 -  Short Execution Time:

• 'table lookup' is 2T
• function execution in 10T
• total cost to call == 12T

Localized lookup:

• localized lookup is 1T
• function execution in 10T
• total cost to call == 11T
• 9% improvement

Example 2 - Long Execution time

• 'table lookup' is 2T
• function execution in 100T
• total cost to call == 102T

Localized lookup:

• localized lookup is 1T
• function execution in 100T
• total cost to call == 101T
• 1% improvement

Generally, I use localization for two reasons:

• Speedup
• Ease of typing (more valuable for your example)

So in your example, I'd simply do this:

```local newText = display.newText -- some speedup, way faster to type.
```

• noriega likes this

[TOPIC: post.html]
#85

### noriega

[GLOBAL: userInfoPane.html]
noriega
• Observer

• • 25 posts
• Corona SDK

Makes sense,  I'm assuming the corona libraries are optimized enough so they are not as long with lookup times vs calling a core lua library .  But yeah, I'll experiment around and see if there is any negligible improvement.

thanks

[TOPIC: post.html]
#86

### Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
• Moderator

• • 26,599 posts
• Enterprise

Can't argue too much with Ed's logic in particular that newText is easier to type that display.newText. The one thing is supportability. I was just looking at a project for someone else and they had abstracted things out and it made it tougher to read.

But on software optimization, you need to decide how often you are calling an API call. For instance, if you only need one random number at the beginning of a scene:create() event, The few microseconds you would gain isn't really perceivable. Our modern devices execute 10's of millions of instructions per second.

Now lets say you're generating a curve and need to call a lot of sin(), cos() and other trig functions in a tight loop, then those few microseconds add up in a hurry.

• noriega likes this

[TOPIC: post.html]
#87

### msahil

[GLOBAL: userInfoPane.html]
msahil
• Enthusiast

• • 35 posts
• Corona SDK

----------------------------------------------------------------------------------------
--
-- main.lua
--
-----------------------------------------------------------------------------------------

local physics = require "physics"

physics.start()
physics.setGravity( 0, 0)
local  math = require("math")
display.setStatusBar(display.HiddenStatusBar)
local outermainarray={}

local h2=820;

local dotsforshootarray = {}
local bulletanglearray={}
local dotarray={}
local pausedcircle11
local pausedcircle
local id=1;
local DX, DY = 3, 3
local XMIN, XMAX = 1, display.contentWidth-1
local YMIN, YMAX = 20, display.contentHeight-1

_W = display.contentWidth; -- Get the width of the screen
_H = display.contentHeight; -- Get the height of the screen
motionx = 0; -- Variable used to move character along x axis
speed = 2; -- Set Walking Speed
local w = display.contentWidth
local h = display.contentHeight
local centerX = display.contentCenterX
local centerY = display.contentCenterY

local myTable = {}

local rect

local Cos = math.cos
local Sin = math.sin
local Atan2 = math.atan2
local Deg = math.deg

local function arc(x, y, radius, theta1, theta2, width, detail)
local vertices = {};
local k = 1;

----------------------------------------------
-- UPRIGHT - Comment out UPSIDE DOWN if using
----------------------------------------------
for i = (360 - theta2), (360 - theta1), detail
do
vertices[k + 1] = radius*math.sin(2*math.pi*(i / 360));
k = k + 2;
end
for i = ((360 - theta1) - ((360 - theta1) % detail)), (360 - theta2), -detail
do
vertices[k] = (radius - width)*math.cos(2*math.pi*(i / 360));
vertices[k + 1] = (radius - width)*math.sin(2*math.pi*(i / 360));
k = k + 2;
end

return display.newPolygon(x, y, vertices), vertices;
end
local function spawnnewloop( event )

print(myTable)
local function spawnnewrings(event)

for s=#myTable,1,-1 do

if myTable[s]~=nil   then
if myTable[s].y>1200 then

transition.cancel( myTable[s] )

display.remove(myTable[s])

myTable[s] = nil
end
end
end

if #myTable<200 then
spawnnew()

end
end

for j=#myTable,1,-1 do
if(myTable[j]~=nil) then
transition.to(myTable[j],{time=2000, y=myTable[j].y+1200,onComplete=spawnnewrings})
end
end

end

local circle2bubble =display.newCircle(display.contentWidth/2,display.contentHeight/2,25)

circle2bubble:setFillColor( 0, 1, 1 )
circle2bubble.x = bubblex
circle2bubble.y = bubbley-364
circle2bubble.linearDamping=0
circle2bubble.myName="bubble"

transition.to(circle2bubble,{time=1000, y=bubbley,x=bubblex})

circle2bubble.isSensor = true
myTable[#myTable+1]=circle2bubble

transition.to(circle2,{time=1000, y=ringy,x=ringx})

end

function spawnnew( event )

if (myTable[#myTable]~=nil) then

h2=myTable[#myTable].y-200

end
for m = 1, 5 do
if(m%5==1) then
spawnBubble(384,h2, 2, -95,2,384,h2,6.5)

end

if(m%5==2)  then
spawnBubble(160,h2, 2, -95,2,160,h2,6.5)
end
if(m%5==3)  then
spawnBubble(520, h2, 2, -95,2,520,h2,6.5)
end

if(m%5==4)  then
spawnBubble(190, h2, 2, -95,2,190,h2,6.5)
end
if(m%5==0)  then
spawnBubble(500, h2, 2, -95,2,500,h2,6.5)
spawnnewloop()

--h2=h2+700
end
h2=h2-200
end

end

spawnnew()

[TOPIC: post.html]
#88

### toril.swift

[GLOBAL: userInfoPane.html]
toril.swift
• Observer

• • 6 posts
• Corona SDK

Hiiiiiii.
This  information is  a  best  and  funtastic  info...i liked this  info  i  want  more   info this
easily types....so you create  more  topics  so you  add me  b cose  i liked very liked this topics

[topic_controls]

[/topic_controls] 