PabloDK
PabloDK

Reputation: 2499

Copy array --> stack or heap overflow?

I have an array named globalArrayAllTrades as you see below. I simply like to INVERT the date in a new copy of the array. So I loop through, create a new object and add it to the new array - simple.

Then function does exactly as expected. BUT if the array contains too many objects the code fails with a "FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory".

My laptop has 8 GB of memory...When the NODEJS process crashes it uses about 1.5 GB and about 70% of of totally amount of available memory is used.

I do run the NODEJS app with the parameter: --max_old_space_size=5000 which normally fixes every thing. But not this one and i have tried MANY different ways to code the same function - BUT each and every time - it fails...unless the original array is smaller.

How can I fix this issue?

 function invertTrades(){

     var original = globalArrayAllTrades.slice();

     globalArrayAllTrades.length = 0;
     globalListAllTrades.length = 0;

     for(var i = 0; i < original.length; i++){

         var objS = original[i];
         var objE = original[original.length-1-i];
         var objInv = new TradePoint(objS.number, objS.matchdate, objE.price, objE.size, objE.issell);

         globalArrayAllTrades.push(objInv);

         globalListAllTrades[objInv.matchdate] = objInv;
     }
 }

Upvotes: 0

Views: 326

Answers (3)

Bergi
Bergi

Reputation: 664464

I would suggest avoiding to copy that array:

function getInverse(i) {
    var objS = globalArrayAllTrades[i];
    var objE = globalArrayAllTrades[globalArrayAllTrades.length-1-i];
    var objInv = new TradePoint(objS.number, objS.matchdate, objE.price, objE.size, objE.issell);
    globalListAllTrades[objInv.matchdate] = objInv;
    return objInv;
}
function invertTrades(){
     globalListAllTrades.length = 0;
     for (var i = 0, l = Math.floor(globalArrayAllTrades.length/2); i < l; i++) {
         var j = globalArrayAllTrades.length-1-i;
         var a = getInverse(i);
         var b = getInverse(j);
         globalArrayAllTrades[i] = a;
         globalArrayAllTrades[j] = b;
     }
 }

Upvotes: 0

Barmar
Barmar

Reputation: 780949

You can save some memory by making original just contain the properties you need to invert, not the whole TradePoint object. Then you don't need to construct new TradePoint objects, you can modify them in place.

var original = globalArrayAllTrades.map(function(trade) {
    return {
        trade.price,
        trade.size,
        trade.issell
    };
}).reverse();
globalArrayAllTrades.forEach(function(trade, i) {
    trade.price = original[i].price;
    trade.size = original[i].size;
    trade.issell = original[i].issell;
});

And since all the objects were modified in place, there's no need to update globalListAllTrades.

Another way is to swap the price, size, and issell properties in place between the pairs of elements:

var midpoint = Math.floor(globalArrayAllTrade.length/2);
for (var i = 0; i < midpoint; i++) {
    var objS = globalArrayAllTrades[i];
    var objE = globalArrayAllTrades[globalArrayAllTrades.length-1-i];

    var temp = objS.price;
    objS.price = objE.price;
    objE.price = temp;

    temp = objS.size;
    objS.size = objE.size;
    objE.size = temp;

    temp = objS.issell;
    objS.issell = objE.issell;
    objE.issell = temp;
}

Upvotes: 1

Jeff McCloud
Jeff McCloud

Reputation: 5927

Have you considered just doing this?

// Copy array and then reverse it
var newArray = [].concat(original).reverse();

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse

Upvotes: 0

Related Questions