Where to put the long lists to save the memory?

Is there a way how to effectively store the long lists to save the run-time memory?

I have problems to fit into the memory with 2D array of N elements. If I split it into the two 1D arrays of N elements, it is a bit better, but still not enough.

I thought, that it might be more effective to store the items in the properties (like 2N scalar values), but unfortunately it isn't. Please, advise me. Thanks! 

  • Lets say you have this:

    var a=[[1,2],[3,4],[5,6]]

    you have 1 object for the main array, and the 3 more for the 3 indexes (numbers are simple objects)  So 4 objects.

    then

    var a1=[1,3,5]

    var a2=[2,4,6]

    that's 2 objects instead of 4. - the two arrays

    now, with a bit of coding, you could have

    var x=[1,3,5,2,4,6], with one object and using the first half and second half

    or

    var y=[1,2,3,4,5,6]

    with one object again, but using even/odd

    so there are a few different ways to cut a bunch of objects down to a few.

  • As you have pointed out, flattening the array is the first step. The reason that storing items in properties isn't more effective at saving memory is because properties are loaded as a dictionary, and dictionaries are expensive. (And properties always take up memory at run-time. You can't selectively load or unload them).

    The 2nd step is to return the array in a function, so that it isn't consuming memory all the time. (If you have large static data in your code, there's a double penalty: memory is used for the code itself, and memory is also used for the object. If you return it in a function, then at least the memory used for the object is transient. Obviously this only helps if you only need the object at certain times, and you have enough free memory at those times to accommodate the object.)

    The 3rd step (for devices with CIQ 2 and higher) is to store the array as a JSON resource: https://developer.garmin.com/connect-iq/core-topics/resources/#jsondata

    The downside of resources is that if you call loadResource() at least once, then the resource symbol tables are permanently loaded into memory. So you lose memory for every resource that is defined (including settings strings). However, the contents of a specific resource are not loaded into memory until you call loadResource() on that resource. This overhead may be worth it if:

    - You are already calling loadResource() for other resources

    - The amount of JSON data is fairly large.

    For devices with CIQ 1, you can't use JSON resources. In this case, it may be possible to encode your data as a long string resource, and decode it in the app. However, you will incur overhead for the code which decodes the string, so it may not be worth it. It may even be possible that the amount of time it takes to decode the string will be long enough to trip the watchdog.

    For my purposes, when I have large data like this:

    - For CIQ 2 devices I use JSON resources

    - For CIQ 1 devices I return the data in a function (and find other ways to save memory, like removing features)

    Another good strategy is to bit-pack your data, if possible.

    e.g. If you are only storing values ranging from 0-255, then you could pack four values into each 32-bit integer, in an array of numbers.