From: marcandre-ruby-core@... Date: 2020-07-15T16:11:41+00:00 Subject: [ruby-core:99180] [Ruby master Bug#17031] `Kernel#caller_locations(m, n)` should be optimized Issue #17031 has been updated by marcandre (Marc-Andre Lafortune). Sure ``` Calculating ------------------------------------- short_backtrace 28.315k (� 7.1%) i/s - 141.984k in 5.044733s long_backtrace 24.168k (� 8.7%) i/s - 120.900k in 5.050243s no_caller_locations 29.288k (� 2.5%) i/s - 148.359k in 5.068723s Total allocated: 1.58 kB (3 objects) Total retained: 0 B (0 objects) Total allocated: 19.58 kB (3 objects) Total retained: 0 B (0 objects) ``` I got a factor 6.2 this time: (1/24.168-1/29.288)/(1/28.315-1/29.288) ---------------------------------------- Bug #17031: `Kernel#caller_locations(m, n)` should be optimized https://bugs.ruby-lang.org/issues/17031#change-86559 * Author: marcandre (Marc-Andre Lafortune) * Status: Open * Priority: Normal * Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN ---------------------------------------- `Kernel#caller_locations(1, 1)` currently appears to needlessly allocate memory for the whole backtrace. It allocates ~20kB for a 800-deep stacktrace, vs 1.6 kB for a shallow backtrace. It is also much slower for long stacktraces: about 7x slower for a 800-deep backtrace than for a shallow one. Test used: ```ruby def do_something location = caller_locations(1, 1).first end def test(depth, trigger) do_something if depth == trigger test(depth - 1, trigger) unless depth == 0 end require 'benchmark/ips' Benchmark.ips do |x| x.report (:short_backtrace ) {test(800,800)} x.report (:long_backtrace ) {test(800, 0)} x.report (:no_caller_locations) {test(800, -1)} end require 'memory_profiler' MemoryProfiler.report { test(800,800) }.pretty_print(scale_bytes: true, detailed_report: false) MemoryProfiler.report { test(800, 0) }.pretty_print(scale_bytes: true, detailed_report: false) ``` Found when checking memory usage on RuboCop. -- https://bugs.ruby-lang.org/ Unsubscribe: