[前][次][番号順一覧][スレッド一覧]

ruby-changes:63163

From: Yusuke <ko1@a...>
Date: Mon, 28 Sep 2020 14:54:50 +0900 (JST)
Subject: [ruby-changes:63163] c55b5f1062 (master): [rubygems/rubygems] Avoid duplicated generation of APISpecification objects

https://git.ruby-lang.org/ruby.git/commit/?id=c55b5f1062

From c55b5f106295aa3c7611a15a9bf7f0d589447ea7 Mon Sep 17 00:00:00 2001
From: Yusuke Endoh <mame@r...>
Date: Fri, 11 Sep 2020 12:00:29 +0900
Subject: [rubygems/rubygems] Avoid duplicated generation of APISpecification
 objects

As far as I could see, `Gem::Resolver::APISpecification` objects are
supposed to be immutable.  If my guessing is correct, then we can cache
and reuse its instances for performance.
At least, `rake` passes on my machine.

Before this change:

```
$ time ruby -I lib bin/gem install --no-doc aws-sdk
Successfully installed aws-sdk-3.0.1
1 gem installed
real    0m37.104s
user    0m36.952s
sys     0m0.333s
```

After this change:

```
$ time ruby -I lib bin/gem install --no-doc aws-sdk
Successfully installed aws-sdk-3.0.1
1 gem installed
real    0m23.905s
user    0m23.740s
sys     0m0.365s
```

https://github.com/rubygems/rubygems/commit/7e8fbba85c

diff --git a/lib/rubygems/resolver/api_specification.rb b/lib/rubygems/resolver/api_specification.rb
index a47d910..232c2b0 100644
--- a/lib/rubygems/resolver/api_specification.rb
+++ b/lib/rubygems/resolver/api_specification.rb
@@ -7,6 +7,17 @@ https://github.com/ruby/ruby/blob/trunk/lib/rubygems/resolver/api_specification.rb#L7
 
 class Gem::Resolver::APISpecification < Gem::Resolver::Specification
   ##
+  # We assume that all instances of this class are immutable;
+  # so avoid duplicated generation for performance.
+  @@cache = {}
+  def self.new(set, api_data)
+    cache_key = [set, api_data]
+    cache = @@cache[cache_key]
+    return cache if cache
+    @@cache[cache_key] = super
+  end
+
+  ##
   # Creates an APISpecification for the given +set+ from the rubygems.org
   # +api_data+.
   #
@@ -18,12 +29,12 @@ class Gem::Resolver::APISpecification < Gem::Resolver::Specification https://github.com/ruby/ruby/blob/trunk/lib/rubygems/resolver/api_specification.rb#L29
 
     @set = set
     @name = api_data[:name]
-    @version = Gem::Version.new api_data[:number]
-    @platform = Gem::Platform.new api_data[:platform]
-    @original_platform = api_data[:platform]
+    @version = Gem::Version.new(api_data[:number]).freeze
+    @platform = Gem::Platform.new(api_data[:platform]).freeze
+    @original_platform = api_data[:platform].freeze
     @dependencies = api_data[:dependencies].map do |name, ver|
-      Gem::Dependency.new name, ver.split(/\s*,\s*/)
-    end
+      Gem::Dependency.new(name, ver.split(/\s*,\s*/)).freeze
+    end.freeze
   end
 
   def ==(other) # :nodoc:
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]