From 1db45026f7912d5c4ffa52e88cb17d2288a9ad67 Mon Sep 17 00:00:00 2001 From: Earlopain <14981592+Earlopain@users.noreply.github.com> Date: Thu, 27 Jun 2024 09:31:22 +0200 Subject: [PATCH] Improve performance for many unresolved includes/extends Potential fix for #1126 --- lib/rdoc/mixin.rb | 10 +++------- test/rdoc/test_rdoc_context.rb | 19 ++++++++++++++++--- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/lib/rdoc/mixin.rb b/lib/rdoc/mixin.rb index fa8faefc15..62aebe9680 100644 --- a/lib/rdoc/mixin.rb +++ b/lib/rdoc/mixin.rb @@ -18,6 +18,7 @@ def initialize(name, comment) @name = name self.comment = comment @module = nil # cache for module if found + @module_lookup_failed = false end ## @@ -64,16 +65,10 @@ def inspect # :nodoc: # - if not found, look into the children of included modules, # in reverse inclusion order; # - if still not found, go up the hierarchy of names. - # - # This method has O(n!) behavior when the module calling - # include is referencing nonexistent modules. Avoid calling #module until - # after all the files are parsed. This behavior is due to ruby's constant - # lookup behavior. - # - # As of the beginning of October, 2011, no gem includes nonexistent modules. def module return @module if @module + return @name if @module_lookup_failed # search the current context return @name unless parent @@ -101,6 +96,7 @@ def module up = up.parent end + @module_lookup_failed = true @name end diff --git a/test/rdoc/test_rdoc_context.rb b/test/rdoc/test_rdoc_context.rb index c4de04e083..c7c641bac8 100644 --- a/test/rdoc/test_rdoc_context.rb +++ b/test/rdoc/test_rdoc_context.rb @@ -409,13 +409,26 @@ def test_add_to_done_documenting refute_includes arr, incl end - def bench_add_include - cm = RDoc::ClassModule.new 'Klass' + def test_bench_add_include + assert_linear_performance (1..25) do |count| + cm = RDoc::ClassModule.new 'Klass' + count.times do |i| + cm.add_include RDoc::Include.new("N::M#{i}", nil) + end + end + end + + def test_bench_include_module_resolution + assert_linear_performance (1..25) do |count| + cm = RDoc::ClassModule.new 'Klass' + cm.store = RDoc::Store.new - assert_performance_linear 0.5 do |count| count.times do |i| cm.add_include RDoc::Include.new("N::M#{i}", nil) end + last_include = RDoc::Include.new("N::M#{count + 1}", nil) + cm.add_include(last_include) + last_include.module end end