Forum Discussion

ioan's avatar
ioan
Roku Guru
9 years ago

Why does having variables global (m.) makes the code slower?

I implemented a motion-jpeg decoder and I tested the code on a computer and a Roku. Now I'm not expecting the Roku to be as fast as the computer, but exactly the same code gets 30+ fps on a computer and ~9-15 fps at most on the Roku when I have all my code in the event loop and ~5-8 fps when I move my code in functions and I have some "m." variables. Just changing the variables to "m.", when I have all my code in the main loop, drops the frame rate by about 5 fps. Why is that? I sure don't want to write a piece of code where everything is in the main() function...  Is there a way around it?
Here is an example. In the following code, if the variable fps is local (no "m.") I get about 604500 loops per second. If I change the variable to m.fps I get about 266300 loops per second.

Library "v30/bslDefender.brs"
sub Main()
    screen = CreateObject("roScreen")
    port = CreateObject("roMessagePort")
    screen.setMessagePort(port)
    codes = bslUniversalControlEventCodes()
    
    timer = CreateObject("roTimespan")    
    timer.Mark()
    m.fps = 0
    while(true)
        msg = port.GetMessage() ' get a message, if available 
        if type(msg) = "roUniversalControlEvent" then
            print "count: "; m.fps; ", total fps: "; (m.fps/(timer.TotalMilliseconds()/1000))
        end if        
        m.fps ++
    end while
end sub

Even not modifying a "m." variable, just accessing the value stored in it slows down the loop, replacing fps++ with fps = fps + m.one (where m.one is declared as m.one = 1) will drop the loops per second from 60000 to 45000. 
Help?

3 Replies

  • Because "dotting" is expensive! Do not be doting on (ab)using "m.vars" - instead use local variables, those are much faster.

    Every time you use "." in B/S, that costs you a symbol lookup in a dictionary (think m.var == m["var"]). That's for assoc.arrays - the situation is much worse when accessing node fields in RSG. Local variables on the other hand have been resolved to index lookups during compilation.
  • "EnTerr" wrote:
    Because "dotting" is expensive! Do not be doting on (ab)using "m.vars" - instead use local variables, those are much faster.

    So if I do this in main()

    m.thing = "bar"
    varr = {foo:"bar"}

    retrieving "bar" from varr will be faster than m in other functions because I have to pass varr as a parameter, making it local?
  • "squirreltown" wrote:

    So if I do this in main()
    m.thing = "bar"
    varr = {foo:"bar"}

    retrieving "bar" from varr will be faster than m in other functions because I have to pass varr as a parameter, making it local?

    I would say "no" from what i see, because in both cases you'd be "dotting" in the function (varr.foo vs m.thing = same difference 8-)). Meanwhile, `m` is "local" to any function, since it's so... special!

    You want to speed up your code for some reason? Pay close attention to the code inside loops (FOR, WHILE) because any penalty there is multiplied by the number of repeats. For example, often some "." and [] indexing can be done outside the loop into a local variable to be used inside. Such optimizations go by the fancy name loop-invariant code motion