Skip to content

set.c: Store set_table->bins at the end of set_table->entries #14179

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

Merged
merged 1 commit into from
Aug 12, 2025

Conversation

byroot
Copy link
Member

@byroot byroot commented Aug 12, 2025

Followup: #14134

This saves one pointer in struct set_table, which would allow Set objects to still fit in 80B TypedData slots even if RTypedData goes from 32B to 40B large.

The existing set benchmark seem to show this doesn't have a very significant impact. Smaller sets are a bit faster, larger sets a bit slower.

It seem consistent over multiple runs, but it's unclear how much of that is just error margin.

compare-ruby: ruby 3.5.0dev (2025-08-12T02:14:57Z master 428937a536) +YJIT +PRISM [arm64-darwin24]
built-ruby: ruby 3.5.0dev (2025-08-12T07:22:26Z set-entries-bounds da30024fdc) +YJIT +PRISM [arm64-darwin24]
warming up........

|                         |compare-ruby|built-ruby|
|:------------------------|-----------:|---------:|
|new_0                    |     15.459M|   15.823M|
|                         |           -|     1.02x|
|new_10                   |      3.484M|    3.574M|
|                         |           -|     1.03x|
|new_100                  |    546.992k|  564.679k|
|                         |           -|     1.03x|
|new_1000                 |     49.391k|   48.169k|
|                         |       1.03x|         -|
|aref_0                   |     18.643M|   19.350M|
|                         |           -|     1.04x|
|aref_10                  |      5.941M|    6.006M|
|                         |           -|     1.01x|
|aref_100                 |    822.197k|  814.219k|
|                         |       1.01x|         -|
|aref_1000                |     83.230k|   79.411k|
|                         |       1.05x|         -|

@byroot byroot marked this pull request as draft August 12, 2025 08:48
This saves one pointer in `struct set_table`, which would allow
`Set` objects to still fit in 80B TypedData slots even if RTypedData
goes from 32B to 40B large.

The existing set benchmark seem to show this doesn't have a very
significant impact. Smaller sets are a bit faster, larger sets
a bit slower.

It seem consistent over multiple runs, but it's unclear how much
of that is just error margin.

```
compare-ruby: ruby 3.5.0dev (2025-08-12T02:14:57Z master 428937a) +YJIT +PRISM [arm64-darwin24]
built-ruby: ruby 3.5.0dev (2025-08-12T07:22:26Z set-entries-bounds da30024fdc) +YJIT +PRISM [arm64-darwin24]
warming up........

|                         |compare-ruby|built-ruby|
|:------------------------|-----------:|---------:|
|new_0                    |     15.459M|   15.823M|
|                         |           -|     1.02x|
|new_10                   |      3.484M|    3.574M|
|                         |           -|     1.03x|
|new_100                  |    546.992k|  564.679k|
|                         |           -|     1.03x|
|new_1000                 |     49.391k|   48.169k|
|                         |       1.03x|         -|
|aref_0                   |     18.643M|   19.350M|
|                         |           -|     1.04x|
|aref_10                  |      5.941M|    6.006M|
|                         |           -|     1.01x|
|aref_100                 |    822.197k|  814.219k|
|                         |       1.01x|         -|
|aref_1000                |     83.230k|   79.411k|
|                         |       1.05x|         -|
```
@byroot byroot marked this pull request as ready for review August 12, 2025 09:49
@byroot byroot requested a review from jeremyevans August 12, 2025 09:49
Copy link
Contributor

@jeremyevans jeremyevans left a comment

Choose a reason for hiding this comment

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

Great work! I think it would be worth considering this approach for st_table, and potentially shrinking hash from 160 bytes to 80 bytes (reducing AR table size from 8 to 3). There are far more hashes than sets, and I would guess that the majority of hashes are likely to have 0-3 entries. Not sure if the potential performance hit for 4-8 entry hashes is worth the memory savings. Hopefully the benchmarks could help determine that.

@byroot
Copy link
Member Author

byroot commented Aug 12, 2025

I think it would be worth considering this approach for st_table,

AFAIK, RHash is only 24B, so st_table can already fit in a 80B slot AFAIK.

@peterzhu2118 do you remember if there is a reason hashes default to 160B slots?

@byroot byroot merged commit 85c5207 into ruby:master Aug 12, 2025
93 of 95 checks passed
@peterzhu2118
Copy link
Member

do you remember if there is a reason hashes default to 160B slots?

Yes, because Hashes using AR tables are 160 bytes in size.

@byroot
Copy link
Member Author

byroot commented Aug 12, 2025

because Hashes using AR tables are 160 bytes in size.

Yes we know that, but they could be whatever size we want. I suppose they were this size before WVA?

@byroot byroot deleted the shink-set-table branch August 12, 2025 21:48
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.

3 participants