0

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;
     }
 }
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
PabloDK
  • 2,181
  • 2
  • 19
  • 42
  • This may answer: http://stackoverflow.com/questions/7193959/memory-limit-in-node-js-and-chrome-v8 – Simon Nov 11 '16 at 00:05
  • @Simon That question is 5 years old. One of the answers says that the memory limit has been removed. – Barmar Nov 11 '16 at 00:09
  • What is `globalListAllTrades`? It seems like you're using it as a key-value-store (object), so `.length = 0` will hardly empty it. – Bergi Nov 11 '16 at 00:12
  • @Bergi You're right, that doesn't do anything, but I don't think it matters. He's replacing all the entries with `globalListAllTrades[objInv.matchdate] = objInv`. – Barmar Nov 11 '16 at 00:13
  • Does the `TradePoint` constructor have any side effects? Why are you making that `original` copy? Where is `globalArrayAllTrades` declared? How large is it (what is `original.length`)? – Bergi Nov 11 '16 at 00:13
  • He's making a copy of the array because he modifies the array with `globalArrayAllTrades.push()` – Barmar Nov 11 '16 at 00:13
  • Nope. I have been running node app. using about 200 GB (YES GB) on big Amazon servers with the option set to --max_old_space_size=200000 without any problems... But it seems like this is not about the total amount of used memory... but more like the size of the heap or stack... but i cant change these... or the parameters to do so - doesnt change any thing... – PabloDK Nov 11 '16 at 00:14
  • @Barmar Yes, I was going to suggest an algorithm that doesn't need the copy if there's no other reason – Bergi Nov 11 '16 at 00:14

3 Answers3

1

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;
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
0

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

Jeff McCloud
  • 5,777
  • 1
  • 19
  • 21
  • he's not just reversing the array. He's combining properties of the objects opposite each other in the array. Look at `objInv`. – Barmar Nov 11 '16 at 00:08
  • Its NOT ALL properties in the array i like to change! The date must be the same - but price and the rest - must be "invert". – PabloDK Nov 11 '16 at 00:10
0

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;
     }
 }
Bergi
  • 630,263
  • 148
  • 957
  • 1,375