Skip to content

Commit

Permalink
feat(array): impl faster splice one element on array
Browse files Browse the repository at this point in the history
  • Loading branch information
fengmk2 committed May 8, 2016
1 parent a6c79e4 commit 92c34e3
Show file tree
Hide file tree
Showing 3 changed files with 201 additions and 4 deletions.
148 changes: 148 additions & 0 deletions benchmark/array_splice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/**
* Copyright(c) node-modules and other contributors.
* MIT Licensed
*
* Authors:
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.com)
*/

'use strict';

/**
* Module dependencies.
*/

var crypto = require('crypto');
var utility = require('../');

var Benchmark = require('benchmark');
var benchmarks = require('beautify-benchmark');
var suite = new Benchmark.Suite();

function arraySplice(array, index) {
array.splice(index, 1);
return array;
}

function spliceOne(array, index) {
for (var i = index, k = i + 1, n = array.length; k < n; i += 1, k += 1) {
array[i] = array[k];
}
array.pop();
return array;
}

class SubArray extends Array {
spliceOne(index) {
for (let i = index, k = i + 1, n = this.length; k < n; i += 1, k += 1) {
this[i] = this[k];
}
this.pop();
return this;
}
}

console.log('arraySplice([1, 2, 3], 1): %j', arraySplice([1, 2, 3], 1));
console.log('new SubArray(1, 2, 3).spliceOne(1): %j', new SubArray(1, 2, 3).spliceOne(1));
console.log('spliceOne([1, 2, 3], 1): %j', spliceOne([1, 2, 3], 1));
console.log('arraySplice([1, 2, 3, 4, 5, 6, 7, 8, 9], 6): %j',
arraySplice([1, 2, 3, 4, 5, 6, 7, 8, 9], 6));
console.log('new SubArray(1, 2, 3, 4, 5, 6, 7, 8, 9).spliceOne(6): %j',
new SubArray(1, 2, 3, 4, 5, 6, 7, 8, 9).spliceOne(6));
console.log('spliceOne([1, 2, 3, 4, 5, 6, 7, 8, 9], 6): %j',
spliceOne([1, 2, 3, 4, 5, 6, 7, 8, 9], 6));

suite

.add('arraySplice([1, 2, 3], 1)', function() {
arraySplice([1, 2, 3], 1);
})
.add('new SubArray(1, 2, 3).spliceOne(1)', function() {
new SubArray(1, 2, 3).spliceOne(1);
})
.add('spliceOne([1, 2, 3], 1)', function() {
spliceOne([1, 2, 3], 1);
})

.add('arraySplice([1, 2, 3, 4, 5, 6, 7, 8, 9], 6)', function() {
arraySplice([1, 2, 3, 4, 5, 6, 7, 8, 9], 6);
})
.add('new SubArray(1, 2, 3, 4, 5, 6, 7, 8, 9).spliceOne(6)', function() {
new SubArray(1, 2, 3, 4, 5, 6, 7, 8, 9).spliceOne(6);
})
.add('spliceOne([1, 2, 3, 4, 5, 6, 7, 8, 9], 6)', function() {
spliceOne([1, 2, 3, 4, 5, 6, 7, 8, 9], 6);
})

.add('arraySplice(new Array(20), 11)', function() {
arraySplice(new Array(20), 11);
})
.add('new SubArray(new Array(20)).spliceOne(11)', function() {
new SubArray(new Array(20)).spliceOne(11);
})
.add('spliceOne(new Array(20), 11)', function() {
spliceOne(new Array(20), 11);
})

.add('arraySplice(new Array(50), 30)', function() {
arraySplice(new Array(50), 30);
})
.add('new SubArray(new Array(50)).spliceOne(30)', function() {
new SubArray(new Array(50)).spliceOne(30);
})
.add('spliceOne(new Array(50), 30)', function() {
spliceOne(new Array(50), 30);
})

.add('arraySplice(new Array(100), 80)', function() {
arraySplice(new Array(100), 80);
})
.add('new SubArray(new Array(100)).spliceOne(80)', function() {
new SubArray(new Array(100)).spliceOne(80);
})
.add('spliceOne(new Array(100), 80)', function() {
spliceOne(new Array(100), 80);
})


.on('cycle', function(event) {
benchmarks.add(event.target);
})
.on('start', function(event) {
console.log('\n map Benchmark\n node version: %s, date: %s\n Starting...',
process.version, Date());
})
.on('complete', function done() {
benchmarks.log();
})
.run({ 'async': false });

// node benchmark/array_splice.js
//
// arraySplice([1, 2, 3], 1): [1,3]
// new SubArray(1, 2, 3).spliceOne(1): [1,3]
// spliceOne([1, 2, 3], 1): [1,3]
// arraySplice([1, 2, 3, 4, 5, 6, 7, 8, 9], 6): [1,2,3,4,5,6,8,9]
// new SubArray(1, 2, 3, 4, 5, 6, 7, 8, 9).spliceOne(6): [1,2,3,4,5,6,8,9]
// spliceOne([1, 2, 3, 4, 5, 6, 7, 8, 9], 6): [1,2,3,4,5,6,8,9]
//
// map Benchmark
// node version: v6.1.0, date: Sun May 08 2016 23:02:25 GMT+0800 (CST)
// Starting...
// 15 tests completed.
//
// arraySplice([1, 2, 3], 1) x 3,391,759 ops/sec ±1.75% (77 runs sampled)
// new SubArray(1, 2, 3).spliceOne(1) x 2,146,665 ops/sec ±2.44% (78 runs sampled)
// spliceOne([1, 2, 3], 1) x 30,957,606 ops/sec ±2.30% (76 runs sampled)
// arraySplice([1, 2, 3, 4, 5, 6, 7, 8, 9], 6) x 3,393,631 ops/sec ±1.58% (81 runs sampled)
// new SubArray(1, 2, 3, 4, 5, 6, 7, 8, 9).spliceOne(6) x 1,898,975 ops/sec ±1.36% (81 runs sampled)
// spliceOne([1, 2, 3, 4, 5, 6, 7, 8, 9], 6) x 23,286,263 ops/sec ±2.40% (72 runs sampled)
// arraySplice(new Array(20), 11) x 3,424,955 ops/sec ±1.39% (79 runs sampled)
// new SubArray(new Array(20)).spliceOne(11) x 1,703,608 ops/sec ±1.43% (79 runs sampled)
// spliceOne(new Array(20), 11) x 6,371,527 ops/sec ±8.68% (71 runs sampled)
// arraySplice(new Array(50), 30) x 2,961,652 ops/sec ±3.94% (81 runs sampled)
// new SubArray(new Array(50)).spliceOne(30) x 1,738,558 ops/sec ±2.28% (84 runs sampled)
// spliceOne(new Array(50), 30) x 2,887,661 ops/sec ±4.01% (74 runs sampled)
// arraySplice(new Array(100), 80) x 2,803,597 ops/sec ±2.12% (86 runs sampled)
// new SubArray(new Array(100)).spliceOne(80) x 1,695,942 ops/sec ±0.91% (88 runs sampled)
// spliceOne(new Array(100), 80) x 3,175,629 ops/sec ±1.28% (86 runs sampled)
36 changes: 32 additions & 4 deletions lib/array.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/*!
* utility - lib/array.js
*
* Copyright(c) 2012 - 2014 fengmk2 <fengmk2@gmail.com>
/**
* Copyright(c) node-modules and other contributors.
* MIT Licensed
*
* Authors:
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.com)
*/

"use strict";
Expand All @@ -27,3 +28,30 @@ exports.randomSlice = function randomSlice(arr, num) {
}
return a;
};

/**
* Remove one exists element from an array
* @param {Array} arr
* @param {Number} index - remove element index
* @return {Array} the array instance
*/
exports.spliceOne = function spliceOne(arr, index) {
if (index < 0) {
index = arr.length + index;
// still negative, not found element
if (index < 0) {
return arr;
}
}

// don't touch
if (index >= arr.length) {
return arr;
}

for (var i = index, k = i + 1, n = arr.length; k < n; i += 1, k += 1) {
arr[i] = arr[k];
}
arr.pop();
return arr;
}
21 changes: 21 additions & 0 deletions test/array.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,24 @@ test('randomSlice() should return sub items', t => {
t.deepEqual(utils.randomSlice(arr, 0), arr);
t.is(utils.randomSlice(arr, 6).length, 6);
});

test('spliceOne() should work', t => {
t.deepEqual(utils.spliceOne([1, 2, 3], 0), [2, 3]);
t.deepEqual(utils.spliceOne([1, 2, 3], 1), [1, 3]);
t.deepEqual(utils.spliceOne([1, 2, 3], 2), [1, 2]);
t.deepEqual(utils.spliceOne([1, 2, 3], 3), [1, 2, 3]);
t.deepEqual(utils.spliceOne([1, 2, 3], 4), [1, 2, 3]);
t.deepEqual(utils.spliceOne([1, 2, 3], 5), [1, 2, 3]);
t.deepEqual(utils.spliceOne([1, 2, 3], -0), [2, 3]);
t.deepEqual(utils.spliceOne([1, 2, 3], -1), [1, 2]);
t.deepEqual(utils.spliceOne([1, 2, 3], -2), [1, 3]);
t.deepEqual(utils.spliceOne([1, 2, 3], -3), [2, 3]);
t.deepEqual(utils.spliceOne([1, 2, 3], -4), [1, 2, 3]);
t.deepEqual(utils.spliceOne([1, 2, 3], -5), [1, 2, 3]);
t.deepEqual(utils.spliceOne([1, 2, 3], 100), [1, 2, 3]);

t.deepEqual(utils.spliceOne([1], 0), []);
t.deepEqual(utils.spliceOne([1], 1), [1]);
t.deepEqual(utils.spliceOne([], 0), []);
t.deepEqual(utils.spliceOne([], 100), []);
});

0 comments on commit 92c34e3

Please sign in to comment.