Performances DOs and DONTs

Hello CIQ team,

When looking to avoid common CIQ development pitfalls and optimize apps for best user experience, one has to go through many different resources: the programmers guide, this forum, video presentations scattered here and there, etc.

Personally, I would think a dedicated chapter in the programmers guide would be ideal. But maybe we can start in a dedicated forum post (this one) and eventually gather all the information in one place ?

Examples given (as far as I understood; corrections welcome):

Ui.View.findDrawableById():
vs Speed/Battery: this can become a costy operation if a layout has many drawables (and all drawables IDs must be string-compared in turn); this can conventienly be cached after View.setLayout() is called
vs Memory: layout drawables are loaded when View.setLayout() is called; caching only creates another reference to the already in-memory object and has minimal memory impact

Ui.loadResource():
vs Speed/Battery: this is a costy operation, especially for large resources like bitmaps or fonts; the result really ought to be cached and "freed" respectively in View.onShow() and View.onHide()
vs Memory: runtime memory will be allocated when Ui.loadResource() is called and "freed" (garbage-collected) once all referring variables are set to null; strings behavior is unclear, especially given the changes introduced in CIQ 2.4 [to be further clarified]
NB: This should be used even for XML-defined strings; using Rez.Strings.XYZ directly in Lang.format() constructs leads to integer numbers being displayed rather than the string themselves [bug?]

Custom fonts:
vs Memory: custom fonts uses as much runtime memory as the corresponding *.fnt/*.png files; one must: 1. limit the quantity of glyphs to those really needed (you might want to anticipate translations and yet-unused accented characters, though); 2. favor bitmap (2-color) glyphs to aliased ones (with much larger *.png file)
vs Speed/Battery: see Ui.loadResource() above

XML layout vs "hardcoded" Graphics.Dc.draw*():
vs Memory: XML layout objects really do take their toll on runtime memory; when memory becomes an issue, using Graphics.Dc.draw*() calls in ad-hoc annotated functions are the way to do, as the cost of convenience
vs Speed/Battery: see Ui.View.findDrawableById() above

Prefer if/else over switch/case:
vs Memory: strange as it sounds, switch/case stanza uses significantly more memory as the if/else equivalent [bug?]

Multi-dimensional arrays():
vs Memory and Speed/Battery: MonkeyC arrays are objects which creation and memory-overhead cost must not be overlooked. In particular, when dealing with multidimensional arrays - which are 1-dimensional arrays of 1-dimensional arrays of ... - one is better server by keeping the first dimension lower than the second dimension than ...; e.g. given a two-dimensional {n} x {N} where {n} << {N}, better have an array made of {n} arrays of {N} elements than the opposite

Avoid nested menus:
vs Memory: nested menus may provide an elegant way of organizing settings and the like but, as each sub-menu is open thanks to Ui.pushView(), the parent menu(s) is(are) kept on the views stack along all the (memory) resources they use

XML resources IDs:
vs Memory: XML resources IDs are strings; in order to retrieve some of those resources at runtime (layout drawables, application properties), one uses those string IDs in the source code, resulting into corresponding static string objects defined in runtime memory; if saving a few hundered bytes becomes a necessity, one could look into using "integer" (string) IDs in the XML resources and matching constants or enums in the source code.
vs Speed/Battery: string comparisons are not the least costy operation; the shorter the strings the better
PS: I understand such optimization may not be applied to properties, which must be identifiable unequivocally across different builds of the application


Other DOs/DONTs ?

Best,

Cédric

EDITED: Thanks Travis and Jim for your responses; original post edited accordingly