Bug #18929


ruby master looks slower than 3.1 on a micro benchmark of short-lived objects

Added by mame (Yusuke Endoh) almost 2 years ago. Updated almost 2 years ago.

Target version:


$ time ruby -ve '10000000.times { }'
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 { }'
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, 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?


clipboard-202207201713-zs81l.png (18.2 KB) clipboard-202207201713-zs81l.png mame (Yusuke Endoh), 07/20/2022 08:13 AM

Updated by peterzhu2118 (Peter Zhu) almost 2 years ago

Thanks for bug report and benchmarking the performance over time! I found a bug that causes thrashing in heap page allocation:

Before this patch:

ruby 3.2.0dev (2022-07-20T16:32:04Z pz-bug-18929 b25ee69e38) [arm64-darwin21]
ruby -ve '50000000.times { }'  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 { }'  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 { }'  3.43s user 0.06s system 99% cpu 3.489 total

Updated by mame (Yusuke Endoh) almost 2 years ago

Thank you for the quick fix! Your patch seems to make sense to me.

Actions #3

Updated by peterzhu2118 (Peter Zhu) almost 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.


Also available in: Atom PDF