Optimization Guidelines

Hi everyone,
First things first: I'm new to MonkeyC, but on good terms with java and been writing for Android + Wear for some time so presumably I know the drill.
Decided to design my own full screen data field and made it run nice on simulator, but when I install it on my Forerunner 230, data field seems to lack performance during actual usage: at least timer field, which I render as two to three
separate strings depending on elapsed time value is rather quirky and most of the time seconds jump around as if there's a half-second delay, then field is redrawn several times in quick succession to make sure data is actual.

I understand that global questions like "why my code runs slow" cannot be answered, thus I ask another vague one: are there specific optimization guidelines/best practices similar to Android Wear ones such as "always prefer object property usage over variable declaration", "clearing dc every onUpdate takes much processing time" etc?

Right now my prime suspects are full screen actions like dc.clear and dc.fillRectangle, but who knows.
If someone is willing to check my code (a little bit cut to fit message limit), then it is provided below.
Sorry for the large plain text, but emulator reports increased memory footprint if I declare a lot of functions.
  • Thank you for this thread! Didn't know about the profiler until i read this. Ran my application and found that onUpdate was executed approx 500 times per second (didn't notice anything on the simulator or my Fenix5plus though), which could be traced back to a loop of WatchUi.requestUpdate(). Easy fix. Slight smile

  • If you add the -k compiler option to monkey c  then newer watches will generate a profile in the logs directory you can load into the profiler to get real hardware results. Make sure you have a copy of the prg.debug.xml file that was generated with your prg file. I copy it into the logs directory when I'm sideloading so it will be in the logs directory when I copy it back out. The simulator profiler was OK in SDK 4.x, but I wouldn't trust it with SDK 6+. Compare the simulator with the hardware results and the problems will be obvious.

  • Hm. How come the profiler is worse in SDK6+? What parts are bad? I guess for my small issue, number of calls to functions, it worked as it should. But it would be interesting to know in which areas I shoudln't trust the profiler.

  • Some examples of profiles from a Fenix 7X vs. simulator:

    Function Fenix 7X Simulator Ratio
    polarXY 204.8 27.8 14%
    transPose 1422.0 197.4 14%
    reTideCalc 131300.0 19370.0 15%
    drawMoonRise 17492.5 2583.0 15%
    calcTicks 100207.0 16379.0 16%
    getInitialView 200571.0 54652.0 27%
    onLayout 113936.0 31467.0 28%
    reDrawHands 8697.3 2408.0 28%
    dateDraw 2326.0 2121.2 91%
    onUpdate 99912.9 96548.7 97%
    getMyPos 9841.2 10373.9 105%
    onPartialUpdate 5645.7 11144.4 197%
    batteryCheck 3284.0 19614.9 597%
    centerPicDraw 1585.6 16174.6 1020%
    getProp 255.3 4993.0 1956%
    initialize 42606.0 1080526.0 2536%
    getVal 5292.0 175549.0 3317%

    onUpdate is the only thing close. onPartialUpdate takes twice as long on the simulator. Functions vary between 7x faster to 33x slower, and there doesn't seem to be any pattern. The onPartialUpdate diagnostics are now 5-6x slower in the simulator, potentially giving a false positive on time exceeded.

  • I wouldn't expect the simulator to give real times for the simulated device. What matters to me are 2 things which IMHO the simulator does correctly: 

    1. Give me an idea which is the slowest part of my code that needs improvement

    2. Compare performance before and after my changes (in percentage, not milliseconds)

  • 1. Give me an idea which is the slowest part of my code that needs improvement

    My point being that this number one isn't the case. The low ratios are false negatives, they could use tuning but the simulator says they're not a problem. The high ratios are false positives, they are not the problem the simulator says they are. The fact that the real world times don't match wouldn't be an issue if the ratios were consistent, but they are all over the place. This was much better with the 4.x SDK's.

    2. Compare performance before and after my changes (in percentage, not milliseconds)

    This is about all it's good for, if you are making big changes. Incremental changes, again it's too inconsistent. We are forced to rely on watch profile data much more than before.

  • Does the order in which you draw objects make a difference? E.g. drawing everything from top to bottom / left to right? I know drawing horizontal lines performs better than vertical lines because on the low level it draws it like an old TV.

  • Nope...  And recall, newer devices have a GPU.

  • Do you recall the source of that intel?

  • Nope...  And recall, newer devices have a GPU.
    Do you recall the source of that intel?

    The fact that CIQ 4+ devices have a GPU is something that "everybody knows" (as it's been repeated in the forums many times *), but there's also anecdotal evidence:

    - CIQ 4 devices have transparency / alpha-blending, other devices do not. e.g. The 945 LTE and 955 have identical map pages, except the buttons are translucent for 955 (CIQ 4) and opaque for 945 LTE (CIQ 3)

    - CIQ 4 devices support anti-aliasing, other devices do not

    - CIQ 4 devices support affine transformations, other devices do not

    (* yeah I realize that fact alone isn't really convincing...)

    Also the SDK release notes (README) refer to devices which have a GPU ("such as venu2") and devices which do not.

    And the System 4 announcement says:

    [https://forums.garmin.com/developer/connect-iq/b/news-announcements/posts/welcome-to-connect-iq-system-4]

    Connect IQ System 4 brings powerful new graphics tools

    I'm sure others have their own sources (maybe the videos or live talks from a Garmin devs conference) but all of that anecdotal evidence is enough for me.