Showing Frames Per Second Meaningfully

– Here is the FPS template I promised in my(Coding On Napkins) comment
– in http://codea.io/talk/discussion/comment/51093#Comment_51093

– Why do programmers care about “Frames Per Second(FPS)”?

– In CODEA, draw() is called 60 times(frames) per second
– or less - much less if the code in draw() takes too long.

– Screen redraw time and response to screen touches
– can become so slow that the user may think your program
– has stopped or gone into an infinite loop.

– This happens because touched() is NOT called until draw() ends.

– One of the hardest tasks a CODEA programmer has is dividing
– a long running task into small enough parts that
– the program remains responsive to user control.

– The most frustrating modern day user “experience” is not being able
– to stop a program or task that the user did not mean to start.

– This very important topic is one I do want to discuss
– another day.

– But back to FPS!

– The CODEA variable DeltaTime gives the time since the last
– call to draw() in seconds. 1/DeltaTime=FPS but it changes
– with every draw().

– You have to provide code to keep a history of DeltaTime’s
– value and interpret what those values mean to your program’s
– response time. That is the topic of this example.

– The easiest way is just to show the instantantious values
– less than, say, 55fps.
– Here is the code:

-- in setup()
    retainedFPS=0
-- in draw()
     monentaryFPS=1/DeltaTime
     if (monentaryFPS<55) then
         retainedFPS=monentaryFPS
     end
     text(string.format("fps=%d",retainedFPS),x,y)
     print(string.format("fps=%d",retainedFPS)..\
)

– The text shows on screen the last “instantanious” value
– and the print records a log into the console.

– In my discussion, I was thinking of a more elaborate
– graphic display with bars for, say,
– inRanges({{55,40},{39.9,20},{19.9,10},{9.9,-1000}}),
– but the simpler code will be enough in many cases.

– I will finish the graphic version because I want it for
– one of y projects.

@CodingOnNapkins - I edited your code section to make it display nicely, and I may have accidentally deleted the end of one line (that now ends with =). Sorry, can you fix?

I’m a little bit confused by this, but I think you got a few things wrong - DeltaTime is the amount of time it took to render the previous frame. 1 / DeltaTime is your frame rate, not your FPS. And touched(touch) doesn’t wait until draw() is done, it waits until the frame is done (there’s a difference).

Also, I wouldn’t worry about programs that take a long time to start up.

@SkyTheCoder FPS means ‘Frames Per Seconds’, also called ‘frame rate’, so they are the same.

@Jmv38 FPS is the amount of frames in the last second, framerate is how fast frames are being made (which can be calculated to an approximate FPS, assuming that every frame was rendering at the same speed). If you want to get more technical about it, tell it to @Andrew_Stacey, he’s the one that told it to me.

lol, I think @SkyTheCoder got you there, @Jmv38 :))
(he would have got me with that, too)

Hi @CodingOnNapkins,

Regarding your point above:

– One of the hardest tasks a CODEA programmer has is dividing – a long running task into small enough parts that – the program remains responsive to user control.

We hit this in our game and I am currently writing a paper called ‘Lessons Learnt Developing A Complex Codea App’

We addressed this in two ways, coroutines which are very powerful, and also having the concept of fine-grained ‘entities’ in a list which is traversed in the draw() call, but each entity has a tick interval, e.g. 0.5 or 1 second, which allows processing time to be ‘federated’…

Brookesi

Sorry folks but I’m into making fast accurate programs — not nitpicking.

As a CODEA coder, I can only control the code I put into Setup(), Draw(), etc.

Only DeltaTime and what I see on the screen during execution tells me if I need to speed up my code. What else goes on, I cannot see nor control so why worry about it before seeing if I can improve my code?

Slow hard-to-use code makes users mad and there is no excuse for it.

Ask any sales clerk or any customer standing in a long line beause the programmers did not worry about speed or how real people would use their code.

Because programmers ignore code speed, computers seem much slower now than when I started in this business in 1963 even if the hardware is thousands of times faster.

BUT the user will forgive you if you show at least once a second what is going on and why its taking so long.

The user wants to do what the user wants to do when the user wants to do it.

Forget this fact and the user will buy code from someone who cares.

@CodingOnNapkins - I also started programming back in the day, and I also like to optimise for speed. If you ever do any 3D programming in Codea, you need all the speed you can get!

I’m not sure of the rationale either for showing instantaneous FPS below some level X, or for showing a bar graph.

FPS can jiggle about a lot, so I have found instantaneous FPS hard to read (with the last digit changing constantly) and distracting.

A bar graph shows you variability but doesn’t give you a clear idea of the user perception of speed. If the FPS over a single second has mostly high and a few low values, the user is probably fine with that, but the graph may not look pretty. For me, a bar chart doesn’t give me much idea of the actual user experience.

The other problem with a bar graph is that FPS can change throughout a program, for example as more objects are added. An average over the entire program is of little value to me. Now sure, you could include a reset button that restarts the chart, but I like to have a value that simply gives me a smoothed average of recent frame rate, so I can monitor what affects it.

@Brookesi

I took so long composing my diatribe that I missed your very good comment.

Please publish your paper as soon as possible.

We all need to known how to make rapidly responding code and the examples and discussion may help us include in CODEA tools to make writing such code fast and easy so everyone will “Think Fast, Accurate, Responsive”

@Ignatz I like all your points about FPS. My graphic FPS may be too elaborate.

I’m beginning to think that the best strategy is to include in every program a simple FPS logger that tells you if any code is slow and what was happening then. This could be as simple as a screen name or drawing function name.

Only log if FPS is very low, say, below one frame/second. so the log does not take up a lot of space.

Leave this hidden in the final product so that if a user complains you can ask for the data.

Only take the time to code more specific fact finding when this crude log says something is too slow.

With the help of the @Brookesi paper, the originsal code should need examination only if something really weird happens.

@CodingOnNapkins - I suggest that the threshold for poor performance is more like 30 FPS, any lower and performance is choppy.

Also, I don’t see any need for a log as a way of detecting speed problems, when it is perfectly obvious from what I can see on the screen.

More important, perhaps, is being able to discover what is causing performance problems. I would suggest that if you are interested in encouraging effective and fast programming, it would be handy to have a set of guidelines and suggestions for new users. For example, local variables are often much faster than global or tabular variables.

I don’t think “one size fits all” works in programming. Suggestions will help to get someone started, but how you do tweaking to increase performance depends on how you code. If you don’t have a good plan on what you’re doing before you start writing code, trying to rewrite code later on isn’t going to help that much. Of course, I don’t follow my own suggestions.

I’m not talking about one size fits all. Some things are just faster, and that’s a fact. It’s very helpful to know what they are, when you need more speed.

A set of guidelines and suggestions for new users is a good idea to get them started, but knowing how to program for speed takes experience. That experience comes from a lot of coding and time learning the language. That can’t be put into writing, hence my “one size fits all” comment. Also, without some way of timing routines and writing it in different ways, you’re not going to know what’s faster. I agree some functions (math for example) are faster depending on how you use them, but as far as I know, there isn’t an easy/accurate way to time routines in Codea.

Hi all,

I use this, its bootstrapped off other peoples ideas, but also displays the Lua VM memory every 5 seconds, framerate as an integer every 0.25 seconds, very useful when you e.g. teardown a view or large object, you should see the memory value drop IF you have nilled out all references correctly…, and chasing down dangling references is a key part of profiling and performance tuning your app… So we alsohad to write a dangling reference finder!

local function metrics()

    if (ElapsedTime - elapsedTimeMem > 5) then
        memory = collectgarbage("count") / 1024
        elapsedTimeMem = ElapsedTime
    end

    pushMatrix()
    resetMatrix()
    pushStyle()
    fill(metricColour)
    font(metricFont)
    fontSize(DefaultStyle.fontSize)
    FPS = FPS * 0.9 + 0.1 / DeltaTime
    if (ElapsedTime - elapsedTimeFPS > 0.25) then
        msg = string.format("%.0fFPS %.1fMB", FPS, memory)
        elapsedTimeFPS = ElapsedTime
    end
    text(msg, WIDTH - 80, 64)
    popStyle()
    popMatrix()
end

I also wrote a Profiler (http://codea.io/talk/discussion/4498/profiler4codea-a-simple-profiling-tool) which allows you to count the number of function calls made in an object, aggregate and average time… I had to write this as our project had got too complicated!

For games with such fast event loops you should also be callling collectgarbage() every 10 seconds or so to ensure objects are cleaned up in a timely manner…

Brookesi

Here is code to show FPS and memory usage

--FPS
-- Frames Per Second
-- Shows maximum, current, minimum fps, memory used and your message
-- to right of CODEA control buttons
-- tap where fps shown to reset max and min to current values
--[===[
-- put in setup()
    -- CODEA controls in bottom left of screen, fps shown to right of them
    CODEAcontrolHeight=40
    CODEAcontrolWidth=265
    garbageCollectAfterThisManySeconds=10 
    fps=FPS(garbageCollectAfterThisManySeconds)
-- put in draw()
    -- use instead of background() to keep CODEA controls showing
    fps:leaveCODEAcontrolsOnScreen(backcolor)
    -- put near end
    fps:draw("your comment here")
-- put in touched(t)
    -- reset fps data if touch where fps is shown
    if t.y<=CODEAcontrolHeight and t.x>=CODEAcontrolWidth then
        fps:init()
    end
--]===]

FPS = class()
 
function FPS:init(garbageCollectAfterThisManySeconds)
    self.fpsnow=1/DeltaTime
    self.fpsmax=self.fpsnow
    self.fpsmin=self.fpsnow
    self.osClock=os.clock()
    self.garbageCollectInterval=garbageCollectAfterThisManySeconds -- seconds
    self.memory=collectgarbage("count")
    self.memmax=self.memory
    self.memmin=self.memory
end

-- background(backcolor) that leaves CODEA controls visible
function FPS:leaveCODEAcontrolsOnScreen(backcolor)
    pushStyle()
    fill(backcolor)
    noStroke()
    rectMode(CORNERS)
    rect(0,CODEAcontrolHeight,WIDTH,HEIGHT)
    popStyle()
end

-- str after RAM, etc.
function FPS:draw(str)
    pushStyle()
    font("Courier")
    fontSize(10)
    textMode(CORNER)
    rectMode(CORNER)
    stroke(0, 0, 0, 255)
    strokeWidth(1)
    fill(255, 255, 255)
    rect(CODEAcontrolWidth,0,WIDTH,CODEAcontrolHeight)
    fill(0, 0, 0, 255)
    self.fpsnow=1/DeltaTime
    self.fpsmax=math.max(self.fpsmax,self.fpsnow)
    self.fpsmin=math.min(self.fpsmin,self.fpsnow)
    if os.clock()>(self.osClock+self.garbageCollectInterval) then
        self.osClock=os.clock()
        self.memory=collectgarbage("count")
        self.memmax=math.max(self.memmax,self.memory)
        self.memmin=math.min(self.memmin,self.memory)
    end
    local s=string.format(  "max=%3d,max=%4dKB\
" -- ,time=%d
                            .."FPS=%3d,RAM=%4dKB\
"
                            .."min=%3d,min=%4dKB",
                     self.fpsmax,self.memmax    -- ,os.clock()
                    ,self.fpsnow,self.memory
                    ,self.fpsmin,self.memmin)
    local w,h=textSize(s)
    text(s,CODEAcontrolWidth+2,5)
    if str~=nil then
        text(str,CODEAcontrolWidth+w+2,5)
    end
    popStyle()
end

function FPS:touched(t)
    -- reset fps data if touch where fps is shown
    if t.y<=CODEAcontrolHeight and t.x>=CODEAcontrolWidth then
        fps:init(self.garbageCollectInterval)
    end
end

I am spending too much time on FPS and not enough on my other projects

Have fun, Coding On Napkins

Personally, I don’t find any of the min, max and last frame speed, useful in practice. The min and max will bounce around, and most recent frame speed is too volatile.

I still prefer to see FPS calculated as the average of recent frames.

Personnally, i need the min (last 2s) too. There are freezes from time to time due to garbage collector or else, and you dont see it via average fps. If you dont have anything moving on screen while coding/testing, you may introduce this glitch, and notice it only long after it was introduced, and have a hard time finding the cause.