From 1bca6cbc29d57dda859323826fa9e534fc461700 Mon Sep 17 00:00:00 2001 From: Julien Portalier Date: Fri, 25 Apr 2025 09:57:58 +0200 Subject: [PATCH] Workaround for #15705: slow compilation of `Crystal.bufferer_message` Inlines the inspect of exceptions into the `Crystal.buffered_message` method to avoid call(s) to `Exception#inspect_with_backtrace(IO)` that causes a dramatic impact on performance when compiling the crystal compiler (and potentially other applications). --- src/crystal/print_buffered.cr | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/crystal/print_buffered.cr b/src/crystal/print_buffered.cr index e58423f0f08b..5208394c83a6 100644 --- a/src/crystal/print_buffered.cr +++ b/src/crystal/print_buffered.cr @@ -31,7 +31,29 @@ module Crystal if exception buf << ": " - exception.inspect_with_backtrace(buf) + + # FIXME: calling `Exception#inspect_with_backtrace` sometimes dramatically + # slows down compilation times, we thus manually print the backtrace + # instead of calling the method. + # + # See https://github.com/crystal-lang/crystal/issues/15705 + # + # exception.inspect_with_backtrace(buf) + loop do + buf << exception.message << " (" << exception.class << ")\n" + + if backtrace = exception.backtrace? + backtrace.each { |line| buf << " from " << line << '\n' } + end + + if ex = exception.@cause + buf << "Caused by: " + exception = ex + next + end + + break + end else buf.puts backtrace.try(&.each { |line| buf << " from " << line << '\n' })