From: "tenderlovemaking (Aaron Patterson) via ruby-core" Date: 2023-09-19T23:45:13+00:00 Subject: [ruby-core:114824] [Ruby master Bug#4040] SystemStackError with Hash[*a] for Large _a_ Issue #4040 has been updated by tenderlovemaking (Aaron Patterson). Hi, We (on the YJIT team) have been tracking Ruby performance. We usually look at YJIT performance as compared to the interpreter, but recently we started looking at interpreter performance (it's getting later in the year so we want to make sure things look good for the release). We noticed there was a degradation in interpreter performance in April, and I tracked the issue to this commit. We were specifically looking at [the chunky png benchmark](https://github.com/Shopify/yjit-bench/blob/main/benchmarks/chunky-png/benchmark.rb). If you check [this graph](https://rubybench.github.io/benchmarks/yjit-bench.html#chunky_png) then click "Time" on the bottom, you can see the increase in time in April. Running `perf stat` on the benchmark shows this commit increases the executed instructions from 232,171,088,239 to 244,008,191,171. Here is the `perf stat` results I got for e7cdce83e8: ``` Performance counter stats for 'ruby -v benchmark.rb': 18,995.65 msec task-clock # 1.000 CPUs utilized 68 context-switches # 3.580 /sec 1 cpu-migrations # 0.053 /sec 33,003 page-faults # 1.737 K/sec 82,022,881,262 cycles # 4.318 GHz (83.32%) 449,576,108 stalled-cycles-frontend # 0.55% frontend cycles idle (83.32%) 21,629,264,292 stalled-cycles-backend # 26.37% backend cycles idle (83.33%) 232,171,088,239 instructions # 2.83 insn per cycle # 0.09 stalled cycles per insn (83.35%) 40,092,228,662 branches # 2.111 G/sec (83.37%) 76,492,242 branch-misses # 0.19% of all branches (83.34%) 18.997823376 seconds time elapsed 18.904486000 seconds user 0.091909000 seconds sys ``` vs `perf stat` for 99c6d19e50 ``` Performance counter stats for 'ruby -v benchmark.rb': 19,415.14 msec task-clock # 1.000 CPUs utilized 66 context-switches # 3.399 /sec 2 cpu-migrations # 0.103 /sec 38,513 page-faults # 1.984 K/sec 82,876,137,933 cycles # 4.269 GHz (83.32%) 577,427,117 stalled-cycles-frontend # 0.70% frontend cycles idle (83.33%) 20,414,833,187 stalled-cycles-backend # 24.63% backend cycles idle (83.35%) 244,008,191,171 instructions # 2.94 insn per cycle # 0.08 stalled cycles per insn (83.37%) 41,385,015,387 branches # 2.132 G/sec (83.35%) 76,702,379 branch-misses # 0.19% of all branches (83.32%) 19.417447024 seconds time elapsed 19.346844000 seconds user 0.068922000 seconds sys ``` It's cool we could fix a 13 year old bug, but given the "rarity" of this issue I'm not sure it's worth the slowdown? ���� I will try to find some way to speed this up, but I'm not sure if I'll have time. In case someone has time to look, the way to reproduce this is by checking out [yjit-bench](https://github.com/shopify/yjit-bench) then running [the chunky-png benchmark](https://github.com/Shopify/yjit-bench/blob/main/benchmarks/chunky-png/benchmark.rb) like this: `perf stat ruby -v benchmark.rb` ---------------------------------------- Bug #4040: SystemStackError with Hash[*a] for Large _a_ https://bugs.ruby-lang.org/issues/4040#change-104668 * Author: runpaint (Run Paint Run Run) * Status: Closed * Priority: Normal * Assignee: ko1 (Koichi Sasada) * ruby -v: ruby 1.9.3dev (2010-11-09 trunk 29737) [x86_64-linux] * Backport: 2.2: UNKNOWN, 2.3: UNKNOWN, 2.4: UNKNOWN ---------------------------------------- =begin I've been hesitating over whether to file a ticket about this, so please feel free to close if I've made the wrong choice. I often use Hash[*array.flatten] in IRB to convert arrays of arrays into hashes. Today I noticed that if the array is big enough, this would raise a SystemStackError. Puzzled, I looked deeper. I assumed I was hitting the maximum number of arguments a method's argc can hold, but realised that the minimum size of the array needed to trigger this exception differed depending on whether I used IRB or not. So, presumably this is indeed exhausting the stack... In IRB, the following is the minimal reproduction of this problem: Hash[*130648.times.map{ 1 }]; true I haven't looked for the minimum value needed with `ruby -e`, but the following reproduces: ruby -e 'Hash[*1380888.times.map{ 1 }]' I suppose this isn't technically a bug, but maybe it offers another argument for either #666 or an extension of #3131. =end -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/