diff options
author | Marc-Andre Lafortune <github@marc-andre.ca> | 2020-12-20 21:42:25 -0500 |
---|---|---|
committer | Hiroshi SHIBATA <hsbt@ruby-lang.org> | 2020-12-23 18:36:08 +0900 |
commit | d4861854ecde00540c527f36aaacd257e63ed5a4 (patch) | |
tree | e618e0a88000d4dac45983be2465e522d9e8d1c8 /lib | |
parent | 0eb2c0c9a2cb66da217b5157419af7b912acb947 (diff) | |
download | psych-d4861854ecde00540c527f36aaacd257e63ed5a4.zip |
[ruby/psych] Make Ractor-ready.
Config is Ractor-local.
Benchmarking reveals that using `Ractor.local_storage` for storing cache
is similar to accessing a constant (~15% slower).
Diffstat (limited to 'lib')
-rw-r--r-- | lib/psych.rb | 26 | ||||
-rw-r--r-- | lib/psych/visitors/visitor.rb | 20 |
2 files changed, 40 insertions, 6 deletions
diff --git a/lib/psych.rb b/lib/psych.rb index 0b62362..cedf0a4 100644 --- a/lib/psych.rb +++ b/lib/psych.rb @@ -632,9 +632,29 @@ module Psych private_class_method :warn_with_uplevel, :parse_caller class << self - attr_accessor :load_tags - attr_accessor :dump_tags - attr_accessor :domain_types + if defined?(Ractor) + require 'forwardable' + extend Forwardable + + class Config + attr_accessor :load_tags, :dump_tags, :domain_types + def initialize + @load_tags = {} + @dump_tags = {} + @domain_types = {} + end + end + + def config + Ractor.current[:PsychConfig] ||= Config.new + end + + def_delegators :config, :load_tags, :dump_tags, :domain_types, :load_tags=, :dump_tags=, :domain_types= + else + attr_accessor :load_tags + attr_accessor :dump_tags + attr_accessor :domain_types + end end self.load_tags = {} self.dump_tags = {} diff --git a/lib/psych/visitors/visitor.rb b/lib/psych/visitors/visitor.rb index 3f4ba64..35f8f81 100644 --- a/lib/psych/visitors/visitor.rb +++ b/lib/psych/visitors/visitor.rb @@ -8,12 +8,26 @@ module Psych private - DISPATCH = Hash.new do |hash, klass| - hash[klass] = "visit_#{klass.name.gsub('::', '_')}" + # @api private + def self.dispatch_cache + Hash.new do |hash, klass| + hash[klass] = :"visit_#{klass.name.gsub('::', '_')}" + end + end + + if defined?(Ractor) + def dispatch + Ractor.current[:Psych_Visitors_Visitor] ||= Visitor.dispatch_cache + end + else + DISPATCH = dispatch_cache + def dispatch + DISPATCH + end end def visit target - send DISPATCH[target.class], target + send dispatch[target.class], target end end end |