Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix deepClone property accessor for an special case #4039

Merged
merged 1 commit into from
Oct 23, 2018
Merged

Fix deepClone property accessor for an special case #4039

merged 1 commit into from
Oct 23, 2018

Conversation

Hugome
Copy link
Contributor

@Hugome Hugome commented Oct 23, 2018

In add to the previous commit :
e1f8da4
To cover special case when the key set/get exist but == undefined :
image

@apollo-cla
Copy link

@Hugome: Thank you for submitting a pull request! Before we can merge it, you'll need to sign the Meteor Contributor Agreement here: https://contribute.meteor.com/

@benjamn
Copy link
Member

benjamn commented Oct 23, 2018

Perhaps we should just unconditionally delete the properties? I know delete is sometimes considered slower than assigning undefined or null (though of course the semantics are different), but deleting a non-existent property should be at least as fast as checking for the property first and then deleting it.

@Hugome
Copy link
Contributor Author

Hugome commented Oct 23, 2018

Your are right, plus deleting non existent property doesn't throw any kind of error/exception.
Push done

@benjamn benjamn merged commit 18dfe93 into apollographql:master Oct 23, 2018
@beeplin
Copy link

beeplin commented Oct 24, 2018

@benhjames @Hugome Unfortunately I tested and found this PR would severely slow down the JS running in browser. Without delete desc.get/set it will cause the JS error previously mentioned, and with delete, after some times of mutations it will be slower and slower, until Chrome warns that it will be out of memory.

As far as I see the 2.4.2 works fine with the old deepClone. Is it necessary to change it to the new one?

@beeplin
Copy link

beeplin commented Oct 24, 2018

If it is not an option to switch back to the old deepClone, I propose to use this:

          if (Object.hasOwnProperty.call(desc, 'get')) delete desc.get
          if (Object.hasOwnProperty.call(desc, 'set')) delete desc.set

Somehow I still feel this is a little bit slower than the old implementation of deep clone, but at least it will handle the set: undefined edge case and is much faster than direct deleting without checking.

@benjamn
Copy link
Member

benjamn commented Oct 24, 2018

I have trouble believing that a delete of a missing property—which should essentially be a no-op—would cause severe memory problems in Chrome. The delete operator has been a feature of JavaScript since before Chrome or V8 existed. Please provide evidence to back up your claims.

@beeplin
Copy link

beeplin commented Oct 24, 2018

I did more tests and now I guess it is not the delete but some other part of the new cloneDeep.js that's causing the slowing problem. The Object.hasOwnProperty way I mentioned above is actually as slow as delete directly.

Sorry for that misleading. Will dig more.

And again, in fact the old implementation works fine.

@benjamn
Copy link
Member

benjamn commented Oct 24, 2018

One thing we can do is not worry about symbol properties or non-enumerable keys, since the previous fclone implementation just used Object.keys. That would simplify the implementation, but still retain the handling of cycles.

benjamn added a commit that referenced this pull request Oct 24, 2018
#4039 (comment)

The previous fclone implementation didn't bother with non-enumerable or
non-string keys, either, so this is not a breaking change.

The Date case was also a bit overzealous, since there are no actual use
cases in this codebase that require Date objects to be duplicated, rather
than simply passing them through.

If we're missing any cases that anyone cares about, we can easily expand
the switch-case coverage in the future.
@benjamn
Copy link
Member

benjamn commented Oct 24, 2018

@beeplin Check out PR #4052!

@beeplin
Copy link

beeplin commented Oct 24, 2018

yeah @benjamn #4052 works and has no performance problem. 👍

benjamn added a commit that referenced this pull request Oct 24, 2018
#4039 (comment)

The previous fclone implementation also did not preserve non-enumerable
or non-string keys, so this is not a breaking change.

The Date case was also a bit overzealous, since there are no actual use cases
in this codebase that require Date objects to be duplicated, rather than simply
passing them through.

If we're missing any cases that anyone cares about, we can easily expand the
switch-case coverage in the future.
@Hugome Hugome deleted the fix-deep-clone branch February 21, 2020 00:00
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants