Created
October 23, 2019 04:54
-
-
Save leodutra/5041f0416235c1f1a92ad149a80bdb4d to your computer and use it in GitHub Desktop.
Fast/elastic array for bad JavaScript engines ( FastArray )
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'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