-
@fanoush I'm not sure what happened in your test, but a 3 char string should only be one var:
Don't have newest build but just retried on 52840 dongle with 2.17 and I still see 2, but in Bangle 2 Emulator I see 1 indeed.
>var a=E.toString(new Uint8Array([1, 2, 3])) ="\1\2\3" >E.getSizeOf(a) =2 >process.memory() ={ free: 13963, usage: 37, total: 14000, history: 10, gc: 0, gctime: 20.6298828125, blocksize: 14, stackEndAddress: 537092008, stackFree: 39728, flash_start: 0, flash_binary_end: 447188, flash_code_start: 516096, flash_length: 1048576 } >process.version ="2v17.450" >trace(a) #24[r1,l1] FlatString [2 blocks] "\1\2\3" =undefined >
EDIT: added trace
EDIT2: maybe that's older E.toString() which still only made flat strings?
-
Thank you for the detailed explanation; it all makes sense now! I've included my code below where I store data in the "compressedData = []" array. Is there a way to save this data with fewer storage blocks or space?
var lastTimestamp = 1692048524472; var lastElevation = 0; var compressedData = []; function compressData(sample) { // Split sample into timestamp and elevation var parts = sample.split("/"); var timestamp = parts[0]; var elevation = Math.round(parseFloat(parts[1]) * 100); // Calculate deltas var deltaTimestamp = (timestamp - lastTimestamp) / 10; // Time difference in tenths of milliseconds var deltaElevation = elevation - lastElevation; // Mask values deltaTimestamp &= 0xff; deltaElevation &= 0xffff; // Create buffer with 1 byte for timestamp delta and 2 bytes for elevation delta var buffer = new Uint8Array(3); buffer[0] = deltaTimestamp; buffer[1] = (deltaElevation >> 8) & 0xff; buffer[2] = deltaElevation & 0xff; console.log("size = " + E.getSizeOf(buffer)); console.log("remaining blocks = " +process.memory().free); // Update last values lastTimestamp = timestamp; lastElevation = elevation; compressedData.push.apply(compressedData, buffer); } setInterval(function(){ compressData("1692048525472/294.35") },500); //the output is this: size = 3 remaining blocks = 11820 size = 3 remaining blocks = 11817 size = 3 remaining blocks = 11814 size = 3 remaining blocks = 11811 size = 3 remaining blocks = 11808 size = 3 remaining blocks = 11805 size = 3 remaining blocks = 11802
There's a small bit of info on http://www.espruino.com/Performance#array-buffers-are-the-most-efficient-way-to-store-data
But basically Uint8Array/etc store their data as a string, but they have to have one variable allocated which explains what type (Uint8/Int16/etc) they are, with size and offset. They also have to link to an ArrayBuffer which then references the string, which is mainly so you can do:
If I just automatically made an ArrayBuffer every time someone referenced
.buffer
then the two buffers wouldn't be equal.You'll say why can't the ArrayBuffer store data directly and the reason is that a String isn't just one datatype - we have string_1,_2,etc depending on the amount of characters in that string block - so we'd have to do the same with ArrayBuffer which would then use up more space in our enum than we have.
It can help to use
trace(..)
sometimes to see what a variable is made of:So it shows
Uint8Array->ArrayBuffer->String
@fanoush I'm not sure what happened in your test, but a 3 char string should only be one var:
So actually the docs are misleading. A String is the most efficient form of storage, but Uint8Array/etc allows you to reference those in a useful way (because normally Strings cannot be modified once created)