Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

New to language, some efficiency questions
Started by DFox May 28 2010 05:56 AM

- - - - -
11 replies to this topic
[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

DFox

[GLOBAL: userInfoPane.html]
DFox
  • Contributor

  • 139 posts
  • Corona SDK

Hi,

First off, I want to say how great I think the Corona SDK is. It's an awesome, awesome tool, and the best $99 I've spent in a long time. I'm working on a game with it, and I had a few questions.

I come from an ActionScript 2/3 background, so it's been very easy to learn Lua. But, I have some efficiency questions that I'm sure a lot of people here know inside and out. These questions might also have to do with how Corona compiles the Lua code.

1. Variable names - does the length of variable names effect efficiency at all? I would assume no since all names are probably dropped at compilation, but I just want to make sure.

2. # of items in table - when you do #mytable, is it doing this calculation each time or is this a property that is stored somewhere? If it's done each time, it makes sense for situations like loops to store it beforehand in a variable, correct?

3. stuff like display.contentWidth - does it provide any efficiency advantage to store properties like that in local variables, or is calling it as the display property just as efficient?

Any insight on these questions is GREATLY appreciated. Also, if you have any other efficiency tips for coding in Lua or Corona, I'd love to hear them.

Thanks in advance!
uid: 6678 topic_id: 1079 reply_id: 301079


[TOPIC: post.html]
#2

MikeHart

[GLOBAL: userInfoPane.html]
MikeHart
  • Corona Geek

  • 1,278 posts
  • Corona SDK

Hi DFox,

this is based on my LUA understanding, if I am incorrect, feel free to correct me:

1) When Lua is translated, it is done into a byte code and so any variable becomes just an offset in the memory. Lua does not translate your source code again and again. This way it does not matter how long your variable names are.

2) Don't store it in a local variable, #table is faster

3) I am not sure if it is more efficent to store these value inside a variable first.

Generally try to test your code on a device early so you can see where the bottlenecks might be. Teh simulator is no indication if your code runs fast. It also can make sence to precalculate math stuff in a table and use it from there. Here are two things I noticed that will give me some speed boost:

Store the function calls from the standard libries like the math lib inside local variables and use these instead:

local mRandom = math.randomlocal mAbs = math.abs -- then use them like thislocal result = mRandom(10,30)local result2 = mAbs(-5,result)


In the same context goes this variation of a function declaration. Instead

local function foo()--your code goes hereend


use this:

local foo = function()--your code goes hereend


I got told that the second version performs faster, probably because of the same method that is used which I described before.

Another thing is that local variables are hold on the stack so they are faster than global variables.

I got my knowledge from here:

http://www.lua.org/gems/sample.pdf
http://trac.caspring.org/wiki/LuaPerformance (Nice performance overview)


uid: 5712 topic_id: 1079 reply_id: 2720


[TOPIC: post.html]
#3

DFox

[GLOBAL: userInfoPane.html]
DFox
  • Contributor

  • 139 posts
  • Corona SDK

Thanks a ton for the information and links! VERY helpful stuff.

After reading the information from the links you provided, I think you might be incorrect about my second question. On the second link, it says a few times that if you can, you should store the number of items in a table in a variable instead of calling #table.

But yeah, thanks again!
uid: 6678 topic_id: 1079 reply_id: 2733


[TOPIC: post.html]
#4

tetu

[GLOBAL: userInfoPane.html]
tetu
  • Contributor

  • 166 posts
  • Corona SDK

hi Mike,

local foo = function()
does not perform faster than
local function foo()

in a problem i have, it performed slightly worse 1373,1374,1375 vs 1373 ms (i ran the test 3 times)
i understand it's better to precalculate math stuff and import the tables with the results.
to do that, i need thousands of lines with the table items

is there a limit to the number of lines we can have in a main.lua file?

uid: 6459 topic_id: 1079 reply_id: 3795


[TOPIC: post.html]
#5

DFox

[GLOBAL: userInfoPane.html]
DFox
  • Contributor

  • 139 posts
  • Corona SDK

tetu, what kind of test did you do? In order to do an accurate speed test, the code needs to be run in a loop thousands or tens-of thousands of times, and the averaged out. Also, is 1373 ms how long it takes one call? I would assume not, but just making sure.

And there's probably no realistic limit for lines in a main.lua file, but theoretically if it was too many lines the device would run out of memory when trying to load it I guess.

But yeah, please post your test code here.
uid: 6678 topic_id: 1079 reply_id: 3796


[TOPIC: post.html]
#6

tetu

[GLOBAL: userInfoPane.html]
tetu
  • Contributor

  • 166 posts
  • Corona SDK

DFox,

all i did is this:
i had 5 local funtion foo lines which i commented and replaced with local foo=function

each function was executed more than a million times

i ran it 3 times, because i thought if Mike's idea was correct i might got some boost

uid: 6459 topic_id: 1079 reply_id: 3798


[TOPIC: post.html]
#7

DFox

[GLOBAL: userInfoPane.html]
DFox
  • Contributor

  • 139 posts
  • Corona SDK

I just did the following test:
local curTime;local inc = 0;local i;local test = function()	inc = inc + 1;endlocal function test2()	inc = inc + 1;endcurTime = system.getTimer();for i = 0, 80000000 do	test();endprint("local test = function() time:"..(system.getTimer() - curTime));inc = 0;curTime = system.getTimer();for i = 0, 80000000 do	test2();endprint("local function test2() time:"..(system.getTimer() - curTime));


With that amount of runs, it still comes out almost identical each time, with the results changing constantly. This leaves me to believe that the difference either way is so minuscule that you're better off just using whichever you like best.
uid: 6678 topic_id: 1079 reply_id: 3799


[TOPIC: post.html]
#8

OderWat

[GLOBAL: userInfoPane.html]
OderWat
  • Contributor

  • 347 posts
  • Corona SDK

I found a lot of those optimization "tricks" not to be working. For example... Calling display.newRect ... Was faster than using a local variable with the function reference. I believe that those tricks may only be true for modules you write yourself in lua and not for this kind of language extensions.

Usually the time bottlenecks are magnitudes bigger than those speed differences and related to inefficient algorithms used in your code. Still having some profiler available would be nice... I use a always visible fps counter and try to have it always on 30 fps ...and I can't really get faster ... But I had to ditch stuff like the polylines... They simply are bugged slow...
uid: 6928 topic_id: 1079 reply_id: 3804


[TOPIC: post.html]
#9

DFox

[GLOBAL: userInfoPane.html]
DFox
  • Contributor

  • 139 posts
  • Corona SDK

Yeah, I agree. Another interesting thing I figured out that in Lua division is faster than multiplication. I thought that was pretty interesting.
uid: 6678 topic_id: 1079 reply_id: 3805


[TOPIC: post.html]
#10

MikeHart

[GLOBAL: userInfoPane.html]
MikeHart
  • Corona Geek

  • 1,278 posts
  • Corona SDK

Well in the simulator you will see hardly a difference. Try on the device. And try to use functions like math.random for an example.

[lua=auto:0]local mrand = math.random
[lua=auto:0]You will see easily the difference it makes.
uid: 5712 topic_id: 1079 reply_id: 3807


[TOPIC: post.html]
#11

OderWat

[GLOBAL: userInfoPane.html]
OderWat
  • Contributor

  • 347 posts
  • Corona SDK

@Mike ...

I tested it on the device and found no noticeable difference for the "real world" case in my application.

It "should" be the same behaviour anyway.. because the Lua implementation will be exact the same between Simulator and Device... just different side effects because of CPU and multitasing / interrupts occur.

I found that it is very difficult to measure any "display..." Object because for some reason.. even if you deallocate everything and run Lua GC (or STOP it)... later runs are always getting slower...

So I used two different programs for testing on the device and the iterations went down to 4000 for 3.5 seconds. Which makes it impractical and artificial to test it anyway.

I just tested with "math.random" and it is really faster using the local variant. But I need 25 times of the iterations than my Rect test version.

Trying to reproduce that with display.newRect() is mood... Taking in consideration that I need about 25 times more iterations to have the same absolute test run time with "math.random" there will be 25 times less difference "always".

The difference for math.random was about 20% with an absolute value of 500 ms in 100.000 iterations

Which boils down to that it does not matter if I use this or that when my fps is at 30 anyway ... (for display.newRect() / display.newImage() that is...)

I still may revert to the "local" variant as even this tiny bit of efficiency may help conserve battery.

But I wonder how the amount of global variables and other side effect may influence this in actual "real world" situations...

Considering that I "delta" all changes to the stage anyway... I could "disable" that and try with my real world app and the framerate average over a longer period of time... I may do that. But even then it stays academical.
uid: 6928 topic_id: 1079 reply_id: 3811


[TOPIC: post.html]
#12

tetu

[GLOBAL: userInfoPane.html]
tetu
  • Contributor

  • 166 posts
  • Corona SDK

Roberto Ierousalimschi, Programming in Lua, 2nd edition, page 51:

"a definition like
local function foo (<params>) <body> end
expands to"

local foo
foo=function (<params>) <body> end
on the same page, he has an example with the factorial function (recursive) where

local fact=function (n) if n==0 then return 1 else return n*fact(n-1) end end
doesn't work, while

local function fact(n) if n==0 then return 1 else return n*fact(n-1) end end
does work

there's no performance difference, thanx to all, but
local function foo()
works for recursive foo's too.

uid: 6459 topic_id: 1079 reply_id: 3829



[topic_controls]
[/topic_controls]