0

I need to create deepclones of veryBigObject. veryBigObject needs to be init first via initVeryBigObject. This is how it looks like:

initVeryBigObject = function(){
    veryBigObject = {};
    ...
    //Very Long Calculations to calculate the value of stuff.
    ...
    veryBigObject = {data:stuff}
}
initVeryBigObject();

var clone = JSON.parse(JSON.stringify(veryBigObject));  //slow

or

eval('createClone = function(){ return ' + JSON.stringify(veryBigObject) + '}');
var clone = createClone();  //turns out to be x3 faster

I'm not a big fan of eval but it's the only fast way I see to clone an object that requires init. Am I missing something?

EDIT: This question isn't really a duplicate of "Most efficient way to clone an object?". The methods talked in "Most efficient way to clone an object?" are about cloning different objects using the same function.

My question is about cloning one particular object multiple times and obviously, methods discussed in "Most efficient way to clone an object?" are far slower than what I'm suggesting with my eval "strategy".

RainingChain
  • 7,397
  • 10
  • 36
  • 68

2 Answers2

1

Tell initVeryBigObject to stop making globals. If you’re copying anything, there’s a high chance you’re doing it wrong.

function initVeryBigObject() {
    return {
        data: stuff // If stuff comes from somewhere else and you need
                    // to clone it, go for deeper object literals.
    };
}

var veryBigObject = initVeryBigObject();
var clone = initVeryBigObject();
Ry-
  • 218,210
  • 55
  • 464
  • 476
  • Initiating veryBigObject takes a very, very long time. I can't call initVeryBigObject every time I need to create a clone, it would take forever. – RainingChain Dec 27 '13 at 04:38
  • I think what he's trying to say is that your very big object is probably not the right approach. This is good practice, create new objects, either with a constructor or a module pattern, instead of cloning. – elclanrs Dec 27 '13 at 04:39
  • @RainingChain: Okay. What’s in it, then? – Ry- Dec 27 '13 at 04:40
  • Well, that's not really a useful information for the problem. Let just say it contains the information about monsters for a game. Calculating the stats/attributes takes a long time. – RainingChain Dec 27 '13 at 04:50
  • What do you mean by deeper object literals? – RainingChain Dec 27 '13 at 04:59
  • @RainingChain: Yes, it is incredibly useful information. Cloning is almost always wrong and you have an XY problem. – Ry- Dec 27 '13 at 05:34
1

I don't know how many hundred times a second you plan to clone your very big object but I created a jsperf test to show the clone speed comparison. One important thing to note is that you're evalutating the same string/object every single time so browsers may memoize some of these results leading to misleading figures.

Anyway the eval way is ugly in that it feels less secure and has been considered bad practice for a while. Not to mention if you have an object with primitive likes, consider {a: new Date(), y: /test/i} it will not clone properly!

Anyway weigh the positives and negatives but the performance benefit from a method like clone should be considered only after functionality! As functionality is not consistent I'd recommend with a iterative approach.

megawac
  • 10,953
  • 5
  • 40
  • 61