Efficient Arrays of Numbers in LocalStorage
This fiddle compares two methods of storing a floating point array in localStorage.
by rhavelka
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
sessionStorage.setItem("myData",JSONcompressed);
var storedString = LZString.decompressFromUTF16(sessionStorage.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)) + "%)";
}