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

perf(marshal): Replace XS-expensive string operations #2001

Merged
merged 2 commits into from
Jan 24, 2024

Conversation

gibson042
Copy link
Contributor

Ref #1982

Description

Speeds up by 21% decoding a representation of the following CopyRecord:

{
  primitives: [undefined, null, true, false, 0, 1, 0n, 1n, "foo", Symbol.for("bar")],
  arrays: [[], [{}]],
  records: { empty: {}, singular: { array: [] } },
}

(and speeds up decoding a CopyArray containing 10 copies thereof by about 100%)

No significant effects in Node.js.

Security Considerations

n/a

Scaling Considerations

As stated on the tin.

Documentation Considerations

n/a

Testing Considerations

n/a

Compatibility Considerations

n/a

Upgrade Considerations

n/a

@gibson042 gibson042 force-pushed the gibson-2024-01-passable-perf branch from d74ddb8 to d02889a Compare January 23, 2024 23:14
@erights erights self-requested a review January 23, 2024 23:26
const tagpayload = decodeArray(encoded.substring(1), decodePassable);
// Skip the ":" inside `decodeArray` to avoid slow `substring` in XS.
// https://github.com/endojs/endo/issues/1984
const tagpayload = decodeArray(encoded, decodePassable, 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const tagpayload = decodeArray(encoded, decodePassable, 1);
const tagPayload = decodeArray(encoded, decodePassable, 1);

Or do you have a convention for when you avoid midcaps? Why? I also notice keysvals above.

Copy link
Contributor Author

@gibson042 gibson042 Jan 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it was preexisting (and git blame git praise) identifies introduction in the landmark Agoric/agoric-sdk#4468). But worth fixing here, which I have done for both sites.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(FWIW I'm surprised I did that and have no idea why I did. Glad to see it fixed, thanks!)

Fail`Unexpected character after u0001 escape: ${c2}`;
elemChars.push(c2);
inEscape = true;
// eslint-disable-next-line no-continue
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a comment on this PR, but curious: Do you think we should turn off warning on continue? I don't see the value in it.

Copy link
Contributor Author

@gibson042 gibson042 Jan 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would love to disable that warning; continue is as useful as break and early return and I don't see any value in discouraging it.

}
elemChars.length === 0 || Fail`encoding terminated early: ${encoded}`;
!inEscape || Fail`unexpected end of encoding ${encoded.slice(skip)}`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point! Expensive operations in that position are fine.

Copy link
Contributor

@erights erights left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

decodePassable with need these same changes, yes?

@gibson042 gibson042 force-pushed the gibson-2024-01-passable-perf branch from d02889a to 3745bab Compare January 23, 2024 23:53
@gibson042
Copy link
Contributor Author

decodePassable with need these same changes, yes?

Both are in the same file and included in this PR (and in fact most of the changes affect decoding).

Ref #1982

Speeds up XS by 21% decoding a representation of the following CopyRecord:
```
{
  primitives: [undefined, null, true, false, 0, 1, 0n, 1n, "foo", Symbol.for("bar")],
  arrays: [[], [{}]],
  records: { empty: {}, singular: { array: [] } },
}
```
(and speeds up decoding a CopyArray containing 10 copies thereof by about 100%)
@gibson042 gibson042 force-pushed the gibson-2024-01-passable-perf branch from 3745bab to dac5bc0 Compare January 23, 2024 23:56
@gibson042 gibson042 enabled auto-merge January 23, 2024 23:56
@erights
Copy link
Contributor

erights commented Jan 23, 2024

decodePassable with need these same changes, yes?

Both are in the same file and included in this PR (and in fact most of the changes affect decoding).

Oops. I mean compactOrdered.
(Admittedly a strange typo to make)

@gibson042 gibson042 merged commit f17b785 into master Jan 24, 2024
14 checks passed
@gibson042 gibson042 deleted the gibson-2024-01-passable-perf branch January 24, 2024 00:04
@gibson042
Copy link
Contributor Author

Ah, yes. I'll do that in the next round of updates to #1594 this week.

gibson042 added a commit that referenced this pull request Jan 25, 2024
Most notably, prefer `charAt(0) === ch` over `startsWith(ch)`.

Ref #1982
Ref #2001
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants