Skip to content

Instantly share code, notes, and snippets.

@leodutra
Created October 23, 2019 04:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leodutra/5041f0416235c1f1a92ad149a80bdb4d to your computer and use it in GitHub Desktop.
Save leodutra/5041f0416235c1f1a92ad149a80bdb4d to your computer and use it in GitHub Desktop.
Fast/elastic array for bad JavaScript engines ( FastArray )
'use strict';
// TODO implement .splice()
// TODO implement .reduce()
// TODO implement .indexOf()
// TODO implement .lastIndexOf()
// TODO implement ECMA5+ <Array> functions
// function fastArrayCopy(srcArray, srcStartIndex, copyStartIndex) {
// var copy = [];
// console.log(arguments)
// while(copyStartIndex--) {
// copy.push(void 0); // fill copy with undefined till start index
// }
// copy.push.apply(copy, srcArray);
// return copy;
// }
var DEFAULT_RELEASE_THRESHOLD = 0.67;
var DEFAULT_RESERVE_THRESHOLD = 1;
module.exports = FastArray;
function FastArray(baseArray, releaseThreshould, reserveThreshould, startIndex) {
// https://jsperf.com/copy-loop-vs-array-slice/13
// http://jsperf.com/new-array-vs-splice-vs-slice/113
// http://jsperf.com/new-array-vs-literal/49
if (this instanceof FastArray) {
var releaseThreshould = releaseThreshould || DEFAULT_RELEASE_THRESHOLD;
var reserveThreshould = reserveThreshould || DEFAULT_RESERVE_THRESHOLD;
var a = baseArray ? fastArrayCopy(baseArray, 0, 0) : [];
var i = startIndex >>> 0;
function reservePreMem(quantity) {
if (i - quantity < 0) {
var mod = parseInt(reserveThreshould * a.length, 10);
if (mod < quantity) mod = quantity;
a = fastArrayCopy(a, i, mod);
i += mod; // put index in front of reserved mem
}
return quantity;
}
function releaseMem(valueCache) {
if (releaseThreshould * a.length < i) {
a = fastArrayCopy(a, i, 0);
i = 0;
}
return valueCache;
}
function fastArrayCopy(srcArray, srcStartIndex, copyStartIndex) {
var copy = [];
while(copyStartIndex--) {
copy.push(void 0); // fill copy with undefined till start index
}
var srcLength = srcArray.length;
while(srcStartIndex < srcLength) {
copy.push(srcArray[srcStartIndex++]);
}
return copy;
}
function unlimitedPushApply(arr, args) {
var totalArgs = args.length;
var argIndex = 0;
while(argIndex < totalArgs) {
// cannot push.apply because of argument limit
arr.push(args[argIndex++]);
}
return arr.length;
}
this.get = function(k) {
return a[i + k];
};
this.push = function() {
return unlimitedPushApply(a, arguments) - i;
};
this.concat = function() {
var copy = fastArrayCopy(a, i, 0);
for(var k = 0, l = arguments.length; k < l;) {
unlimitedPushApply(copy, arguments[k]);
}
return copy;
};
this.unshift = function() {
var k = reservePreMem(arguments.length);
var arr = a;
while (k--) {
arr[--i] = arguments[k];
}
return arr.length - i;
};
this.length = function() {
return a.length;
};
this.pop = function() {
if (i < a.length) return releaseMem(a.pop());
};
this.shift = function() {
if (i < a.length) return releaseMem(a[i++]);
};
this.clone = function() {
return new FastArray(a, 0, 0, i);
};
this.clear = function() {
var cleared = a.length;
a = [];
i = 0;
return cleared;
}
this.toString = function() {
return fastArrayCopy(a, i, 0).toString();
};
this.toJSON = function() {
return JSON.stringify(fastArrayCopy(a, i, 0));
};
this.toArray = function() {
return fastArrayCopy(a, i, 0);
};
}
}
FastArray.prototype = {
constructor: FastArray
};
// // // TESTS
// var i, j, o, t;
// var mod = 1000000;
// t = Date.now();
// i = mod;
// o = [];
// while (i--) {
// o.push(1, 2, 3, 4, 5, 6);
// }
// t = Date.now() - t;
// console.log(t + '\t' + 'Array.push()');
// t = Date.now();
// i = mod;
// while (i--) {
// o.pop();
// o.pop();
// o.pop();
// o.pop();
// o.pop();
// o.pop();
// }
// t = Date.now() - t;
// console.log(t + '\t' + 'Array.pop()\n');
// // t = Date.now();
// // i = mod;
// // o = [];
// // while (i--) {
// // o.unshift(1, 2, 3, 4, 5, 6);
// // }
// // t = Date.now() - t;
// // console.log('Array.unshift() ' + t);
// // t = Date.now();
// // i = mod;
// // while (i--) {
// // o.shift();
// // o.shift();
// // o.shift();
// // o.shift();
// // o.shift();
// // o.shift();
// // }
// // t = Date.now() - t;
// // console.log(t + '\t' + 'Array.shift() ' );
// t = Date.now();
// i = mod;
// o = new FastArray();
// while (i--) {
// o.unshift(1, 2, 3, 4, 5, 6);
// }
// t = Date.now() - t;
// console.log(t + '\t' + 'FastArray.unshift()');
// t = Date.now();
// i = mod;
// while (i--) {
// o.shift();
// o.shift();
// o.shift();
// o.shift();
// o.shift();
// o.shift();
// }
// t = Date.now() - t;
// console.log(t + '\t' + 'FastArray.shift()');
// t = Date.now();
// i = mod;
// o = new FastArray();
// while (i--) {
// o.push(1, 2, 3, 4, 5, 6);
// }
// t = Date.now() - t;
// console.log(t + '\t' + 'FastArray.push()');
// t = Date.now();
// i = mod;
// while (i--) {
// o.pop();
// o.pop();
// o.pop();
// o.pop();
// o.pop();
// o.pop();
// }
// t = Date.now() - t;
// console.log(t + '\t' + 'FastArray.pop()\n');
// t = Date.now();
// i = mod;
// o = new FastArray();
// while (i--) {
// o.unshift(1, 2, 3, 4, 5, 6);
// }
// t = Date.now() - t;
// console.log(t + '\t' + 'FastArray.unshift()');
// t = Date.now();
// i = mod;
// while (i--) {
// o.push(1, 2, 3, 4, 5, 6);
// }
// t = Date.now() - t;
// console.log(t + '\t' + 'FastArray.push() after unshift');
// t = Date.now();
// i = mod;
// o = new FastArray();
// while (i--) {
// o.unshift(1, 2, 3, 4, 5, 6);
// }
// t = Date.now() - t;
// console.log(t + '\t' + 'FastArray.unshift() after push\n');
// t = Date.now();
// i = mod;
// o = new FastArray();
// while (i--) {
// o.push(6);
// }
// t = Date.now() - t;
// console.log(t + '\t' + 'FastArray.push() one arg');
// t = Date.now();
// i = mod;
// o = [];
// while (i--) {
// o.push(6);
// }
// t = Date.now() - t;
// console.log(t + '\t' + 'Array.push() one arg');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment