-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
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
Add a new HashSet template #61194
Add a new HashSet template #61194
Conversation
reduz
commented
May 19, 2022
- Intended to replace RBSet in most cases.
- Optimized for iteration speed
Some tests: Raw dataAverage of 10 runs.
|
@lawnjelly props seems your algorithm idea was pretty good! @bruvzg what is the weirdest here is that iteration is faster in the STL one. in HashSet iteration is literally just an array! |
Eh, the graphs aren't marked.. what is time and what is the number of executions? |
Y - time (µs, log scale), X - number of iterations. |
LLVM black magic? When it's built with GCC it's not faster. The previous test was with LLVM 13, this one with GCC 11.3: And MSVC 17.2: Probably it's doing some low-level optimizations, like autovectorization that's can't be easily done with the custom iterator. |
As always, I would like to take credit when it goes right, and when it goes wrong it was all your idea. 😀 I would actually be tempted to go further and try fully decoupling the two resizes (the keys versus the actual hashmap list). The keys could be stored as a vector and resized with a x2 basis (which reduces the resizes of the key, which could be expensive if they are big). EDIT: Ah I now see the One thing I noticed is that although the non-pot might reduce hash collisions, it means you have to use a % operator instead of just a bitwise AND to wraparound. Hash collisions phasing is probably super important to avoid but worth a mention, I don't know whether all use cases are susceptible to this phasing. Also it might be an idea to try templating the As I say I think this approach of separating the expensive elements and using an ID in the hashmap list may also work well for the unordered hashmap. |
5a9da0a
to
d7c294e
Compare
Leak sanitizer is detecting lots of leaks (in ShaderLanguage?), see https://github.com/godotengine/godot/runs/6528386338?check_suite_focus=true |
* Intended to replace RBSet in most cases. * Optimized for iteration speed
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.
Looks good to me, early benchmarks seem promising. I did a quick sanity check that editor startup and rendering of a simple 3D scene didn't regress (same speed as before).
Thanks! |
For reference, here's a benchmark of editor startup/shutdown on an empty project:
|
@Calinou all these changes show that, despite criticism that we were not using the most efficient data structures in most cases, in the end (now that we are) it makes little to no difference because these structures were not used for critical areas. |
Fixes godotengine#97066 `RBSet` were used on `RotatedFileLogger` because it guarantees that iterating it is done via `operator<`. This is important because `RotatedFileLogger` depends on this behavior to delete the oldest log file. On godotengine#61194 `HashSet` was added and all `RBSet` uses were replaced by `HashSet`. When that happened, the iteration in order is guaranteed to be the insertion order, wich made that `RotatedFileLogger` delete the newest log file. As a bonus, I added unit test for `RotatedFileLogger` and `CompositeLogger`.
Fixes godotengine#97066 `RBSet` were used on `RotatedFileLogger` because it guarantees that iterating it is done via `operator<`. This is important because `RotatedFileLogger` depends on this behavior to delete the oldest log file. On godotengine#61194 `HashSet` was added and all `RBSet` uses were replaced by `HashSet`. When that happened, the iteration in order is guaranteed to be the insertion order, wich made that `RotatedFileLogger` delete the newest log file. As a bonus, I added unit test for `RotatedFileLogger` and `CompositeLogger`.
Fixes godotengine#97066 `RBSet` were used on `RotatedFileLogger` because it guarantees that iterating it is done via `operator<`. This is important because `RotatedFileLogger` depends on this behavior to delete the oldest log file. On godotengine#61194 `HashSet` was added and all `RBSet` uses were replaced by `HashSet`. When that happened, the iteration in order is guaranteed to be the insertion order, wich made that `RotatedFileLogger` delete the newest log file. As a bonus, I added unit test for `RotatedFileLogger` and `CompositeLogger`.
Fixes godotengine#97066 `RBSet` were used on `RotatedFileLogger` because it guarantees that iterating it is done via `operator<`. This is important because `RotatedFileLogger` depends on this behavior to delete the oldest log file. On godotengine#61194 `HashSet` was added and all `RBSet` uses were replaced by `HashSet`. When that happened, the iteration in order is guaranteed to be the insertion order, wich made that `RotatedFileLogger` delete the newest log file. As a bonus, I added unit test for `RotatedFileLogger` and `CompositeLogger`.
Fixes godotengine#97066 `RBSet` were used on `RotatedFileLogger` because it guarantees that iterating it is done via `operator<`. This is important because `RotatedFileLogger` depends on this behavior to delete the oldest log file. On godotengine#61194 `HashSet` was added and all `RBSet` uses were replaced by `HashSet`. When that happened, the iteration in order is guaranteed to be the insertion order, wich made that `RotatedFileLogger` delete the newest log file. As a bonus, I added unit test for `RotatedFileLogger` and `CompositeLogger`.
Fixes godotengine#97066 `RBSet` were used on `RotatedFileLogger` because it guarantees that iterating it is done via `operator<`. This is important because `RotatedFileLogger` depends on this behavior to delete the oldest log file. On godotengine#61194 `HashSet` was added and all `RBSet` uses were replaced by `HashSet`. When that happened, the iteration in order is guaranteed to be the insertion order, wich made that `RotatedFileLogger` delete the newest log file. As a bonus, I added unit test for `RotatedFileLogger` and `CompositeLogger`.