Removing Array Elements

I have an array and I want to remove N elements from the head.

Lets say an array (with floats) has 1M elements, and I want the first 500K to come out. I have two ways: switching the call 500K times per cycle or connecting the call (0,500000).

The fact is that the first solution is a terrible idea (very very slow). The second one is also slow, because splice returns the deleted part from the array in the new array (well, it just selects 500K floats and throws them out of the window).

In my application, I do some things with really large matrices, and unfortunately, removing elements through splicing is slow for me. Is there a faster way to achieve this?

+4
source share
2 answers

I would expect it to Array#slicebe at least as fast as any of these options, and probably faster. This means a temporary distribution of duplicated memory, but 1M numbers are only about 64 MB of memory (provided that the JavaScript engine was able to use a true array under covers), so temporarily have the original 64 MB plus 32 MB for the ones you want to keep before release 64MB of the original seems pretty cheap:

array = array.slice(500000);

This also has the advantage that it will not force the JavaScript engine to use the object, not the array under the covers. (Other things you do can cause this, but ...)

, float, Float64Array . , , , . , , , , . ( JavaScript , , .)

( , , ). NodeJS , splice 60% 95% , slice, V8 , slice:

"use strict";
let sliceStats = createStats();
let sliceTypedStats = createStats();
let spliceStats = createStats();
for (let c = 0; c < 100; ++c) {
    if (test(buildUntyped, sliceStats, testSlice).length != 500000) throw new Error("1");
    if (test(buildTyped, sliceTypedStats, testSlice).length != 500000) throw new Error("2");
    if (test(buildUntyped, spliceStats, testSplice).length != 500000) throw new Error("3");
    console.log(c);
}
console.log("slice     ", avg(sliceStats.sum, sliceStats.count));
console.log("sliceTyped", avg(sliceTypedStats.sum, sliceTypedStats.count));
console.log("splice    ", avg(spliceStats.sum, spliceStats.count));

function avg(sum, count) {
    return (sum / count).toFixed(3);
}

function createStats() {
    return {
        count: 0,
        sum:   0
    };
}
function buildUntyped() {
    let a = [];
    for (let n = 0; n < 1000000; ++n) {
        a[n] = Math.random();
    }
    return a;
}

function buildTyped() {
    let a = new Float64Array(1000000);
    for (let n = 0; n < 1000000; ++n) {
        a[n] = Math.random();
    }
    return a;
}

function test(build, stats, f) {
    let a;
    let ignore = 0;
    let start = Date.now();
    for (let i = 0; i < 10; ++i) {
        let s = Date.now();
        a = build();
        ignore += Date.now() - s;
        a = f(a);
    }
    stats.sum += Date.now() - start - ignore;
    ++stats.count;
    return a;
}

function testSlice(a) {
    return a.slice(500000);
}
function testSplice(a) {
    a.splice(0, 500000);
    return a;
}
+2

Immutable.js . , , . Immutable.js, splice.

+1

All Articles