-
Notifications
You must be signed in to change notification settings - Fork 13.4k
rustdoc search: prefer stable items in search results #141658
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
base: master
Are you sure you want to change the base?
rustdoc search: prefer stable items in search results #141658
Conversation
rustbot has assigned @GuillaumeGomez. Use |
Some changes occurred in HTML/CSS/JS. |
This comment has been minimized.
This comment has been minimized.
e40eefb
to
d35829b
Compare
Nevermind, the only difference is a new array in the search index, so should be very limited, and only an impact on std/core/alloc crates. |
// sort unstable items later | ||
a = Number( | ||
// @ts-expect-error | ||
this.searchIndexUnstable.get(aaa.item.crate).contains(aaa.item.bitIndex), |
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.
Instead of retrieving this information every time, why not storing this information in the related item when we build the search index?
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.
yeah, you're right, we should keep linear scans out of inner loops if possible.
if we have a binary search impl, or if we ever pull one in in the future, we could actually use that to speed up the unpacking time for the search index (since we can pre-sort them when generating the index), though it's probably not worth embedding a binary search impl for something that only speeds up the standard libraries.
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.
Ah, right, I copied this from the implementation of deprecated items sorting, so if we want to change one, we should probably change all of them (especially because those ones will be applicable to all crates).
Also, we have RoaringBitmap, so it's not a linear scan, actually.
I'm not sure what the memory impact of having 3 more boolean fields on each row is (especially when one of those is going to be unused in every non-sysroot crate), so I would kinda wanna do some degree of perf testing to see if this is worth it.
One thing we could do actually would be to add this data during transformResults
, that way we're not adding a field to everything in the search index, only to the results that are currently being show, so we would only ever do 1 bitmap lookup per item per search, which may be better than doing it per comparsion, except for the fact that we're not doing it once per comparison, we're only doing it to compare when the items have the same edit distance, which is actually fairly likely to be less than the number of results.
TL;DR it's actually not obvious what the most performant solution would be, so I'd rather stick with what the code is already doing and then maybe make a followup PR focused on performance.
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.
Adding this data when we build the search index seems like the way to go.
As for performance checking, @notriddle wrote a tool for it (which you can find here if I'm not wrong).
There are multiple ways of limiting the impact on performance. Another idea I had would be to put the new comparison in a function which would be created during search index creation: if we don't have any stability information, then the function is empty.
Anyway, it'll likely impact performance of all crates using rustdoc (both std/core/alloc and the others without stability info) so I'd really prefer to ensure what the impact is before approving it.
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.
Another idea I had would be to put the new comparison in a function which would be created during search index creation: if we don't have any stability information, then the function is empty.
Is a dynamic function call faster than a searching an empty bitmap?
I suppose JITs have the advantage that they can inline closures dynamically, but I'm not sure how significant it would be.
I'm trying to run the perf tool, but i'm having a bit of trouble making a full custom toolchain, probably due to bootstrap settings.
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 got it "working" and I think it's a bit out of date:
Testing T ... TypeError: searchModule.execQuery is not a function
at Object.doSearch (/home/binarycat/src/rs/rustdoc-js-profile/src/tester.js:229:37)
at main (/home/binarycat/src/rs/rustdoc-js-profile/src/tester.js:316:49)
at Object.<anonymous> (/home/binarycat/src/rs/rustdoc-js-profile/src/tester.js:327:1)
at Module._compile (node:internal/modules/cjs/loader:1734:14)
at Object..js (node:internal/modules/cjs/loader:1899:10)
at Module.load (node:internal/modules/cjs/loader:1469:32)
at Module._load (node:internal/modules/cjs/loader:1286:12)
at TracingChannel.traceSync (node:diagnostics_channel:322:14)
at wrapModuleLoad (node:internal/modules/cjs/loader:235:24)
at Module.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:152:5)
@GuillaumeGomez the i should look at how much bigger the standard library index is, thought. |
@@ -736,6 +741,7 @@ pub(crate) fn build_index( | |||
crate_data.serialize_field("r", &re_exports)?; | |||
crate_data.serialize_field("b", &self.associated_item_disambiguators)?; | |||
crate_data.serialize_field("c", &bitmap_to_string(&deprecated))?; | |||
crate_data.serialize_field("u", &bitmap_to_string(&unstable))?; |
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.
Could we add this field only if unstable
is not empty?
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 could, although i'm pretty sure it would make most doc bundles bigger, as the logic for handling the undef field would be more than 6 bytes, even when minified (i believe this is why we don't omit other fields either, even tho many crates have no reexports or aliases)
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.
Good point, I'll keep that in a corner of my memory until I have some idea on how to make it better.
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 can get part of the way there by noticing js truthiness rules are just sane enough for this case, the only falsy string value is the empty string, so we can do | ""
to cleanse the undef. we're still using a few chars for the field access though, so i think in order to make this profitable we have to put this in a loop and apply it to multiple fields. unfortunately our fields are not homogeneous, so we'll need a different default value for different fields, meaning we'd be barely breaking even in the average case.
honestly if we want to make the search index smaller, we're much better off chasing an improvement that scales, like delta compressing the row ids, instead of trying to save a single digit number of bytes.
Yeah, after re-reading, I realized I was wrong. So yeah, only impact should be in std/core/alloc crates. Would be nice to have some numbers for them. Although I don't expect the impact to be that big. So seems like a very good start, just a few nits and it should be ready for merge. |
Based on my limited testing, this adds 8KiB to the It's a bit worse in terms of compressed size, 0.8%, but it's still not super significant, but it's also only 1.8KB compressed. |
It's acceptable, but now we have numbers. |
d35829b
to
341866a
Compare
fixes #138067
this does add a new field to the search index, but since we're only listing unstable items instead of adding a boolean flag to every item, it should only increase the search index size of sysroot crates, since those are the only ones using the
staged_api
feature, at least as far as the rust project is concerned.