Efficient Arrays of Numbers in LocalStorage

This fiddle compares two methods of storing a floating point array in localStorage.

by Christopher O

HTML

<script src="https://wihl.github.io/DGMD-E27-S16-Assignments/js/lz-string.min.js"></script>
<p>
The purpose of this fiddle is to find a more efficient means of storing a large
set of floating point numbers in localStorage. localStorage only supports storing
strings, so what is the best means to store many floating point numbers?
</p>
<h4>
Method:
</h4>
<ol>
<li>Create an array of 1000 random floating point numbers.</li>
<li>Convert this array into a localStorage compatible string by both JSON and Base64 encoding.</li>
<li>Compress each string using <a href="http://pieroxy.net/blog/pages/lz-string/index.html" target="_new">LZ compression written in JavaScript</a> while still maintaining
localStorage compatibility.(Note the use of External Resources in this JSfiddle to host
a copy of Pieroxy's library.)</li>
<li>Finally, we write and read to localStorage just to make sure it worked.</li>
</ol>
<p>
The result shows a dramatic improvement in size. So instead of a 5MB limit in localStorage
this means can allow up to 4x as much storage, effectively allowing 20MB. While Base64 has better compression, compressed JSON overall takes less space.
</p>
    <p><b>Output:</b>
    </p>
    <div id="output"></div>

JavaScript

// Step 1: Create an array of floating point numbers
var arr = [];
for (var i = 0; i < 1000; i++){
	arr.push(Math.random());
}

// Step 2: Convert to JSON and Base64 and see length
var JSONarr = JSON.stringify(arr);
logMessage ("The JSON string length is: " + JSONarr.length);
var B64arr = btoa(arr);
logMessage ("The Base 64 string length is: " + B64arr.length);

// Step 3: Compress the resulting arrays
var JSONcompressed = LZString.compressToUTF16(JSONarr);
logMessage ("The compressed JSON string length is: " + JSONcompressed.length +
						pct(JSONcompressed.length, JSONarr.length));
var B64compressed = LZString.compress(B64arr);
logMessage ("The compressed Base64 encodded string length is: " + B64compressed.length +
						pct(B64compressed.length, B64arr.length));

// Step 4: Make sure it works using the best method, which is JSONcompressed
localStorage.setItem("myData",JSONcompressed);
var storedString = LZString.decompressFromUTF16(localStorage.getItem("myData"));
var storedArr = JSON.parse(storedString);
for (i = 0; i < arr.length; i++){
	if (arr[i] !== storedArr[i]) {
  	alert("It didn't work!");
  }
}
logMessage ("Storing and reading back from localStorage worked.")


// Utility function for logging convenience
// Logs msg to the element with given id
// If id is undefined, logs to #output
    function logMessage(msg, id) {
        if (!id) {
            id = "output";
        }
        document.getElementById(id).innerHTML += msg + "<br>";
    }
    
    
// Utility function to show a ratio as a formatted percentage string
	function pct(nom,denom) {
  	return " (" + (Math.floor((1 - nom / denom)*100)) + "%)";
  }