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

Optimize anchorset and flex tree traversal #22717

Merged
merged 6 commits into from
Oct 3, 2024

Conversation

CraigMacomber
Copy link
Contributor

Description

Optimizations based on a profile of BubbleBench.

This resulted in about 5% more bubbles (80 vs 76).

Given this application's read costs scale with bubbles squared (for the collision logic), contains writes, and most reads are leaf values which are not impacted by this, this seems like a pretty good win. Some real apps could probably show significantly larger gains if they are less leaf heavy or less write heavy.

Reviewer Guidance

The review process is outlined on this wiki page.

@CraigMacomber CraigMacomber requested review from a team as code owners October 2, 2024 23:34
@github-actions github-actions bot added area: dds Issues related to distributed data structures area: dds: tree changeset-present base: main PRs targeted against main branch labels Oct 2, 2024
* @param index - index being looked for.
* @returns child with the requested parentIndex, or undefined.
*/
function binaryFind(sorted: readonly PathNode[], index: number): PathNode | undefined {
Copy link
Contributor

Choose a reason for hiding this comment

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

does this function really not exist anywhere else in our codebase??

Copy link
Contributor

Choose a reason for hiding this comment

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

(a parameterized binary search, I mean...obiously there are pathnode specifics in here)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I started with a more generic binary search which returned the index, but this was so dominated by small data sizes (0 and 1 are the common array sizes here) that it had a lot of overhead (forces an extra array lookup, key extraction or comparison callback, JS lacks a 3 way compare operator so thats annoying etc). I did find another binary search implementation, but it was not exposed in a generically useful way either.

I have added a comment about this.

* Gets a child if it exists.
* Does NOT add a ref.
*/
tryGetChild(key: FieldKey, index: number): AnchorNode | undefined;
Copy link
Contributor

Choose a reason for hiding this comment

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

it's a bit odd that child (which isn't named getChild?) returns an UpPath, and tryGetChild returns an AnchorNode. perhaps some naming cleanup could be done here for clarity?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this makes sense (though I'm biased as I wrote it). child, as a noun named thing, has to be low cost and without side-effects, so it returns the a path to the child, which is the child if there is already an AnchorNode for it. It could be renamed to getChild, but in my opinion thats more verbose, and less informative, since it loses some of the low-cost connotation when adding get.

tryGetChild is the 'try' version of that, but try needs a verb form, so we have tryGet, which returns the child AnchorNode if it exists, without forcing one to exist.

We then have getOrCreateChild, which unconditionally returns an AnchorNode.

While I think that all makes since, you are right its a bit inconsistent due to the "get" being force on the "try" version for mostly grammatical reasons. Perhaps childIfAnchored would be a better name for it as it keeps the noun structure? I have done that rename.

@msfluid-bot
Copy link
Collaborator

msfluid-bot commented Oct 3, 2024

@fluid-example/bundle-size-tests: +1.24 KB
Metric NameBaseline SizeCompare SizeSize Diff
aqueduct.js 460.47 KB 460.5 KB +35 Bytes
azureClient.js 557.45 KB 557.5 KB +49 Bytes
connectionState.js 724 Bytes 724 Bytes No change
containerRuntime.js 259.74 KB 259.76 KB +14 Bytes
fluidFramework.js 405.32 KB 405.83 KB +525 Bytes
loader.js 134.34 KB 134.36 KB +14 Bytes
map.js 42.46 KB 42.46 KB +7 Bytes
matrix.js 148.63 KB 148.64 KB +7 Bytes
odspClient.js 524.41 KB 524.46 KB +49 Bytes
odspDriver.js 97.84 KB 97.86 KB +21 Bytes
odspPrefetchSnapshot.js 42.81 KB 42.82 KB +14 Bytes
sharedString.js 164.82 KB 164.83 KB +7 Bytes
sharedTree.js 395.78 KB 396.28 KB +518 Bytes
Total Size 3.31 MB 3.31 MB +1.24 KB

Baseline commit: a9c881f

Generated by 🚫 dangerJS against 30352f5

Copy link
Contributor

@alexvy86 alexvy86 left a comment

Choose a reason for hiding this comment

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

Approving for docs, with a few suggestions. Did not look in depth at the functional changes.

.changeset/spicy-candles-smash.md Outdated Show resolved Hide resolved
.changeset/spicy-candles-smash.md Outdated Show resolved Hide resolved
@CraigMacomber CraigMacomber merged commit 6a2b681 into microsoft:main Oct 3, 2024
28 checks passed
@CraigMacomber CraigMacomber deleted the fastBubble branch October 3, 2024 18:35
sonalideshpandemsft pushed a commit that referenced this pull request Oct 7, 2024
## Description

Optimizations based on a profile of BubbleBench.

This resulted in about 5% more bubbles (80 vs 76).

Given this application's read costs scale with bubbles squared (for the
collision logic), contains writes, and most reads are leaf values which
are not impacted by this, this seems like a pretty good win. Some real
apps could probably show significantly larger gains if they are less
leaf heavy or less write heavy.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: dds: tree area: dds Issues related to distributed data structures base: main PRs targeted against main branch changeset-present
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants