-
Notifications
You must be signed in to change notification settings - Fork 54
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: remove use of Object.defineProperties in CID class #202
Conversation
`Object.defineProperties` is a performance bottleneck in applications that create lots and lots of CIDs (e.g. IPFS) so this PR removes it. The `asCID` property is changed to be a [private class field](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields) which requires increasing the minimum supported EcmaScript version but I don't know if that's a big deal or not. It does seem to make the property non-enumerable though. The CID class now implements a `Link` interface that has public `byteOffset` and `byteLength` properties so these become regular properties `code`, `version`, `multihash` and `bytes` become writable/configurable but they are marked with `@readonly` so maybe that's enough? Fixes #200
Targets the upcoming v10.0.0 branch and not master so needs #199 merging first. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with this I think, it's a breaking change but we could bundle it into 10.0.0 safely I think. The byteOffset
and byteLength
properties are going to be the major actual break here as they'll now be showing up when enumerating properties. Hopefully there's not a common case for doing that though, I can't think of one.
If it's a problem, you can do the whole prefix-with-# + getter trick that's being done with |
I have to admit, I'm a little confused by the |
Discussion on Feel free to speak up if you disagree and want to make a case for this increasing complexity or confusion or? |
I'll open a separate issue, it's unrelated to this PR |
@achingbrain are you currently shipping private class fields anywhere in distributed code in js-ipfs or js-libp2p? We don't do a compile step here now so this is going straight out to users and will be the base of almost everything in our stack. How many users are we going to give headaches to? Node 12 and Chrome 74, but what about all the edges of old Safari etc. that we want to push our stack to? .. i.e. are we ready for the hadache? |
I'm also remembering that we have uses of Probably not the worst thing to just remove that, but it has been handy as a very fast initial check that this thing might be a CID. |
src/cid.js
Outdated
|
||
asCID: hidden | ||
}) | ||
get asCID () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, this is making it public again? so this is essentially a hack to make a hidden property? sneaky.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is going to survive the structural cloning which is what going to occur when transferring CIDs across realms/threads.
If it does not it would defeat the purpose
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Gozala are there any tests that guard against regressions around this? I can't see anything obvious.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should have, but we did not as far as I can tell. I have created one #206
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW I don't believe there is any problem with making asCID
public other than it would break JSON.stringify(cid)
which could be addressed by having toJSON
method.
So maybe it's worth just making it a regular property and call it a day.
yeah, ok, so let's just go with this.
|
I thought we did but - the syntax is certainly used but it's all typescript and looking into the published code tsc has converted it to use WeakMaps. |
I might be missing something but is this not the kind of place you'd just pass it to |
Can check some assumptions here ?
IMO As long as we keep |
yeah, it's certainly not necessary and really just exists as a super-shortcircuit since that function is operating on the full object graph so will be hitting lots of objects that may or may not be a CID, so we get to do a quick simple check and avoid additional logic in the
I don't recall the original justification for hiding them, it may be have been to do with https://github.com/ipld/is-circular which I think we've now migrated off anyway. I'm inclined toward a Chesterton's Fence one this one given there may be dragons, but the question about the performance tradeoff is a good one - |
2022-10-04 IPLD triage note: @rvagg is going to sync with @achingbrain about making asCID as regular property. |
* chore: add test for structural copying * fix: remove generated import * fix: lint errors * fix: another attempt to make eslint happy * chore: and another attemp to make eslint happy
8013f93
to
e398180
Compare
e398180
to
fb69544
Compare
#206 was merged into here, demonstrating the realm problem. I've simplified the code here and made Merging it with those change in to #199, will pause for feedback before we release. |
Object.defineProperties
is a performance bottleneck in applications that create lots and lots of CIDs (e.g. IPFS) so this PR removes it.The
asCID
property is changed to be a private class field which requires increasing the minimum supported EcmaScript version but I don't know if that's a big deal or not. It does seem to make the property non-enumerable though.The CID class now implements a new
Link
interface that has public read-onlybyteOffset
andbyteLength
properties so these become regular properties. Similarlycode
,version
,multihash
andbytes
become writable/configurable but they are also marked with@readonly
so maybe that's enough?Fixes #200