Preserving memory in Monkey C


As for couple of last days I was fighting hard to preserve every single byte of memory, balancing just at the edge... maybe others will find that usefull - and even more - maybe Garmin will work on that to improve as well?

1. Do not use SWITCH / CASE construction. Instead - use IF / ELSE IF construction. It preserves memory, maybe not a lot, but always few bytes or more.

2. This is ridiculous? Do not use CONST variables. It looks like using directly values preserves memory. Don?t like it, but no choice there

3. It is beneficial to create a function whenever 2 or 3 lines of code are repeated. Just use params if required. It will save space

4. Avoid use of dictionaries!

5. For memory consuming operation try to assign to every non used variable NULL ? this will free memory

I'd appreciate - as the whole community - if others would share their findings too!
  • I agree, after that, reading the code is not at all easy.
    I think these are Garmin programmers errors. These constants should have been converted at compile time.
    But we are where we are.

  • In most of my apps, I hard code a color in this way, so for setting colors, it will be something like

    dc.setColor(MySettings.time,MySettings.trans);

    Where in "MySettings" what I get from settings is mapped using

    hidden var colors=[Gfx.COLOR_WHITE,Gfx.COLOR_LT_GRAY,Gfx.COLOR_DK_GRAY,Gfx.COLOR_BLACK,	//0-3
    		Gfx.COLOR_RED,Gfx.COLOR_DK_RED,Gfx.COLOR_ORANGE,Gfx.COLOR_YELLOW,				//4-7
    		Gfx.COLOR_GREEN,Gfx.COLOR_DK_GREEN,Gfx.COLOR_BLUE,Gfx.COLOR_DK_BLUE,			//8-11
    		Gfx.COLOR_PURPLE,Gfx.COLOR_PINK,Gfx.COLOR_TRANSPARENT];
    		
    		// then in the code when the settings are read
    		
    		time=colors[<value read from settings for this color>];

    where I could use the value to reduce the size of an app by a few bytes, the code is still easy to read.  I think it was the fenix 3 where pink and purple were backwards, and by doing it this way things worked.

    Some folks probably just hard code the values right with the settings so there's no mapping

  • Yes, that's what I meant about hard coding the value in settings.  I found it easier to just use an index into an array than the actual value.

  • I went the other way:

    Set in setting

    </setting>
    <setting propertyKey="@Properties.CT" title="@Strings.Color_Time">
        <settingConfig type="list">
            <listEntry value="16711680">@Strings.RED</listEntry>
            <listEntry value="11141120">@Strings.DK_RED</listEntry>
            <listEntry value="16733440">@Strings.ORANGE</listEntry>
            <listEntry value="16755200">@Strings.YELLOW</listEntry>
            <listEntry value="65280">@Strings.GREEN</listEntry>
            <listEntry value="43520">@Strings.DK_GREEN</listEntry>
            <listEntry value="43775">@Strings.BLUE</listEntry>
            <listEntry value="255">@Strings.DK_BLUE</listEntry>
            <listEntry value="16711935">@Strings.PINK</listentry>
            <listentry value="11141375">@Strings.PURPLE</listEntry>
            <listEntry value="11184810">@Strings.GRAY</listEntry>
            <listEntry value="5592405">@Strings.DK_GRAY</listEntry>
        </settingConfig>

    Then in the code

    // read user setting
    ColorTime = mApp.getProperty("CT"); 
    
    
    // then in the code when the settings are read
    dc.setColor(ColorTime, -1);
    

  • And if I understand correctly, the value in the array takes up more memory than if these values were in separate variables:
    For example, in your code there is an array MySettings
    dc.setColor (MySettings.time, MySettings.trans);

    however, code with two separate variables will take up less memory:
    dc.setColor (time, trans);

  • As far as the array, yes it's got 14 values, but things don't change with that if I call setColor() 10 times or 50 times.  We're talking just a small handful of bytes to use the array.  And if it does get that tight, I can hard code the values, or switch to having the values in settings, but I never get that tight in an app.

    Readability along with consistency between all my apps.

    BTW, MySettings is a class, not an array, so time and trans are simple variables.

  • Sorry, I really made a little mistake with the class MySettings

  • Just a note on my experience, as I've found that while the memory used by an array is small, the amount of memory that gets used to initialize an array with values is actually quite expensive. (Counts as code memory I think?)

    Even relatively small arrays (12 values) I've started loading them from jsondata when the app starts up as it works out cheaper memory wise.

  • I second the idea about using direct values instead of the constants defined by the SDK. I went a different way with it than suggested here: I used inline literals with comment next to each one explaining it's original value:

    var font = someCondition ? 2 /* Gfx.FONT_SMALL */ : 5 /* Gfx.FONT_NUMBER_MILD */

    Saved about 700 bytes overall by doing this with all colours, fonts, text justification consts.

  • Is there a memory profiler built into the SDK that I don't know about? I'm basing my memory optimisation entirely on the status bar in the device simulator - I opened the "Memory" view in Eclipse but it's always blank...