-O 2pz vs -O 3pz

I thought this was interesting and worth sharing, since I wasn't able to find info on it online: I ran the profiler on my watch when I compiled with -O 2pz and with -O 3pz, and 2pz actually was faster/more efficient. That made me curious to try with -O 1pz, and it was slightly more efficient than -O 3pz, but not by much. So at least for me, I'm going to stick with -O 2pz

The test I ran was simply running the simulator with the profiler, and using time simulation to speed it up and run for about 16 sim hours

Here are my results with -O 3pz:

-O 3pz

Here are my results with -O 2pz:

-O 2pz

And here are my results with -O 1pz:

-O 1pz

Has anyone else seen this in their apps/watchfaces? How big of a difference do the different options make for your code?

  • I haven't look into this (I optimize for code size), but since all this was measured on the simulator, I'm not sure how accurate it is, or whether the same tendency is true on the real devices...

    But the biggest flow in what you do is that you pass 2 flags that by design are contradicting each other: "p" and "z". You should decide whether you want to optimize for code size and pass only z, or optimize for speed/performance and pass only p

  • According to the docs, they're not mutually exclusive developer.garmin.com/.../ But, maybe someone from the Garmin team can add some clarity on whether using both 'p' and 'z' might lead to stepping on the toes of one or the other? In other words, will a binary generated with -O2z be smaller than one generated with -O2pz? Will a binary generated with -O2p be more performant than one generated with -O2pz? If so, is there a way to tell the compiler which to prioritize? For me, I would want to optimize for performance, and then get any size optimizations that won't reduce performance. For you, it sounds like you'd want any performance optimizations that won't increase size.

    Or are they synergistic? For example, I could see performance optimizations removing or collapsing redundant logic more aggressively, which in turn results in a smaller binary. Or I could see size optimizations collapsing operations into a small size which is also more perfomant

    I wonder how different the results on device would be. I also find it strange that calls to dc.drawText{) generate such expensive Long.toNumber calls

  • Interestingly, exporting my project (https://github.com/jm355/wf) with -O 2pz, -O 2p, and -O 2z, and interestingly enough the smallest wf.iq binary was -O 2p at 1,726,375 bytes. -O 2z  was the second smallest at 1,726,492 bytes, and the largest was -O 2pz at 1,726,523

  • If you don't use it yet, then you might find this extension useful: https://forums.garmin.com/developer/connect-iq/f/discussion/294852/big-update-to-prettier-extension-monkeyc and also though it's probably the longest thread in the forum, and some parts of it get outdated with newer and newer sdk versions because of how the compiler changes, it's worth to read through it.

  • Ooh very cool, thank you!