From dd2f57bd4eacbb1acbf56299035ceb2191fe35be Mon Sep 17 00:00:00 2001 From: Soutaro Matsumoto Date: Mon, 29 Aug 2022 20:56:02 +0900 Subject: [PATCH 1/2] Reduce Namespace/TypeName instantiation --- lib/rbs/namespace.rb | 10 ++++++---- lib/rbs/type_name_resolver.rb | 4 ++-- sig/namespace.rbs | 6 ++++++ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/lib/rbs/namespace.rb b/lib/rbs/namespace.rb index d41496436..67b2ef3f9 100644 --- a/lib/rbs/namespace.rb +++ b/lib/rbs/namespace.rb @@ -10,11 +10,11 @@ def initialize(path:, absolute:) end def self.empty - new(path: [], absolute: false) + @empty ||= new(path: [], absolute: false) end def self.root - new(path: [], absolute: true) + @root ||= new(path: [], absolute: true) end def +(other) @@ -30,8 +30,10 @@ def append(component) end def parent - raise "Parent with empty namespace" if empty? - self.class.new(path: path.take(path.size - 1), absolute: absolute?) + @parent ||= begin + raise "Parent with empty namespace" if empty? + self.class.new(path: path.take(path.size - 1), absolute: absolute?) + end end def absolute? diff --git a/lib/rbs/type_name_resolver.rb b/lib/rbs/type_name_resolver.rb index 87d1059ed..d32466c21 100644 --- a/lib/rbs/type_name_resolver.rb +++ b/lib/rbs/type_name_resolver.rb @@ -37,11 +37,11 @@ def resolve(type_name, context:) query = Query.new(type_name: type_name, context: context) try_cache(query) do - path_head, *path_tail = type_name.to_namespace.path + path_head, *path_tail = type_name.split raise unless path_head name_head = TypeName.new(name: path_head, namespace: Namespace.empty) - + absolute_head = context.find do |namespace| # @type break: TypeName full_name = name_head.with_prefix(namespace) diff --git a/sig/namespace.rbs b/sig/namespace.rbs index fc505d7c6..3ab23affd 100644 --- a/sig/namespace.rbs +++ b/sig/namespace.rbs @@ -38,6 +38,12 @@ module RBS @absolute: bool + @parent: Namespace? + + self.@root: Namespace? + + self.@empty: Namespace? + # Returns new _empty_ namespace. def self.empty: () -> Namespace From 5f565df999a6c694114fd2503306d03ca128f61b Mon Sep 17 00:00:00 2001 From: Soutaro Matsumoto Date: Fri, 2 Sep 2022 11:08:47 +0900 Subject: [PATCH 2/2] Reduce empty array/hash allocation --- lib/rbs/types.rb | 26 +++++++++++++++++++++----- sig/types.rbs | 4 ++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/lib/rbs/types.rb b/lib/rbs/types.rb index 1f5699344..ff3406a52 100644 --- a/lib/rbs/types.rb +++ b/lib/rbs/types.rb @@ -845,12 +845,12 @@ def free_variables(set = Set.new) def map_type(&block) if block Function.new( - required_positionals: required_positionals.map {|param| param.map_type(&block) }, - optional_positionals: optional_positionals.map {|param| param.map_type(&block) }, + required_positionals: amap(required_positionals) {|param| param.map_type(&block) }, + optional_positionals: amap(optional_positionals) {|param| param.map_type(&block) }, rest_positionals: rest_positionals&.yield_self {|param| param.map_type(&block) }, - trailing_positionals: trailing_positionals.map {|param| param.map_type(&block) }, - required_keywords: required_keywords.transform_values {|param| param.map_type(&block) }, - optional_keywords: optional_keywords.transform_values {|param| param.map_type(&block) }, + trailing_positionals: amap(trailing_positionals) {|param| param.map_type(&block) }, + required_keywords: hmapv(required_keywords) {|param| param.map_type(&block) }, + optional_keywords: hmapv(optional_keywords) {|param| param.map_type(&block) }, rest_keywords: rest_keywords&.yield_self {|param| param.map_type(&block) }, return_type: yield(return_type) ) @@ -859,6 +859,22 @@ def map_type(&block) end end + def amap(array, &block) + if array.empty? + _ = array + else + array.map(&block) + end + end + + def hmapv(hash, &block) + if hash.empty? + _ = hash + else + hash.transform_values(&block) + end + end + def map_type_name(&block) map_type do |type| type.map_type_name(&block) diff --git a/sig/types.rbs b/sig/types.rbs index 92f358c7b..7a565621e 100644 --- a/sig/types.rbs +++ b/sig/types.rbs @@ -404,6 +404,10 @@ module RBS def drop_tail: () -> [Param, Function] def has_keyword?: () -> bool + + def amap: [A, B] (Array[A]) { (A) -> B } -> Array[B] + + def hmapv: [X, Y, Z] (Hash[X, Y]) { (Y) -> Z } -> Hash[X, Z] end class Block