Bug #18929
closedruby master looks slower than 3.1 on a micro benchmark of short-lived objects
Description
$ time ruby -ve '10000000.times { Object.new }'
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
real 0m2.503s
user 0m2.484s
sys 0m0.016s
$ time ./local/bin/ruby -ve '10000000.times { Object.new }'
ruby 3.2.0dev (2022-07-20T00:40:59Z master e330dceb3f) [x86_64-linux]
real 0m3.074s
user 0m3.016s
sys 0m0.052s
I plotted a graph for daily commits in this year:
We can see a clear slowdown before and after 2022-05-09. As far as I checked each commit on the day, https://github.com/ruby/ruby/commit/85479b34f76d5b426c2a8224d8ed6d8c2ad81ca2 seems a trigger, but reverting this commit did not change the performance.
It's just a microbenchmark, but I think there may be room for improvement. @peterzhu2118 (Peter Zhu) Could you check it out?
Files
Updated by peterzhu2118 (Peter Zhu) over 2 years ago
Thanks for bug report and benchmarking the performance over time! I found a bug that causes thrashing in heap page allocation: https://github.com/ruby/ruby/pull/6156.
Before this patch:
ruby 3.2.0dev (2022-07-20T16:32:04Z pz-bug-18929 b25ee69e38) [arm64-darwin21]
ruby -ve '50000000.times { Object.new }' 4.34s user 0.13s system 99% cpu 4.517 total
After this patch:
ruby 3.2.0dev (2022-07-20T12:40:31Z pz-bug-18929 86d061294d) [arm64-darwin21]
ruby -ve '50000000.times { Object.new }' 3.48s user 0.05s system 99% cpu 3.547 total
Ruby 3.1:
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [arm64-darwin21]
ruby -ve '50000000.times { Object.new }' 3.43s user 0.06s system 99% cpu 3.489 total
Updated by mame (Yusuke Endoh) over 2 years ago
Thank you for the quick fix! Your patch seems to make sense to me.
Updated by peterzhu2118 (Peter Zhu) over 2 years ago
- Status changed from Open to Closed
Applied in changeset git|cdbb9b8555b4ddcc4c557f25ad785cae6209478d.
[Bug #18929] Fix heap creation thrashing in GC
Before this commit, if we don't have enough slots after sweeping but
had pages on the tomb heap, then the GC would frequently allocate and
deallocate pages. This is because after sweeping it would set
allocatable pages (since there were not enough slots) but free the
pages on the tomb heap.
This commit reuses pages on the tomb heap if there's not enough slots
after sweeping.