class Symbol
  def to_msgpack_ext
    [to_s].pack('A*')
  end

  def self.from_msgpack_ext(data)
    data.unpack('A*').first.to_sym
  end
end
class Symbol
  # to_msgpack_ext is supposed to return a binary string.
  # The canonical way to do it for symbols would be:
  #  [to_s].pack('A*')
  # However in this instance we can take a shortcut
  if method_defined?(:name)
    alias_method :to_msgpack_ext, :name
  else
    alias_method :to_msgpack_ext, :to_s
  end

  def self.from_msgpack_ext(data)
    # from_msgpack_ext is supposed to parse a binary string.
    # The canonical way to do it for symbols would be:
    #  data.unpack1('A*').to_sym
    # However in this instance we can take a shortcut
    data.to_sym
  end
end

Optimize Symbol to_msgpack_ext and from_msgpack_ext
Optimize Symbol to_msgpack_ext and from_msgpack_ext

```ruby
require 'benchmark/ips'
require 'msgpack'

symbol = :foo

original_factory = MessagePack::Factory.new
original_factory.register_type(0x00, Symbol)
original_payload = original_factory.dump(symbol)

optimised_factory = MessagePack::Factory.new
optimised_factory.register_type(0x00, Symbol, packer: Symbol.method_defined?(:name) ? :name.to_proc : :to_s.to_proc, unpacker: :to_sym.to_proc)
optimised_payload = optimised_factory.dump(symbol)

raise "Format change" unless original_payload == optimised_payload

puts "== #{RUBY_DESCRIPTION} =="
puts
puts "-- load --"
Benchmark.ips do |x|
  x.report('original load') { original_factory.load(original_payload) }
  x.report('optimised load') { optimised_factory.load(optimised_payload) }
  x.compare!
end

puts "-- dump --"
Benchmark.ips do |x|
  x.report('original dump') { original_factory.dump(symbol) }
  x.report('optimised dump') { optimised_factory.dump(symbol) }
  x.compare!
end
```

```
== ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin19] ==

-- load --
Warming up --------------------------------------
       original load    89.559k i/100ms
      optimised load    96.724k i/100ms
Calculating -------------------------------------
       original load    904.759k (± 2.0%) i/s -      4.568M in   5.050463s
      optimised load    976.025k (± 1.6%) i/s -      4.933M in   5.055455s

Comparison:
      optimised load:   976024.9 i/s
       original load:   904758.9 i/s - 1.08x  (± 0.00) slower

-- dump --
Warming up --------------------------------------
       original dump    63.903k i/100ms
      optimised dump    87.429k i/100ms
Calculating -------------------------------------
       original dump    631.579k (± 1.4%) i/s -      3.195M in   5.059979s
      optimised dump    862.071k (± 1.3%) i/s -      4.371M in   5.071797s

Comparison:
      optimised dump:   862071.2 i/s
       original dump:   631579.1 i/s - 1.36x  (± 0.00) slower
```

```
== ruby 3.0.0p0 (2021-01-14 revision 42098249b2) [x86_64-darwin19] ==

-- load --
Warming up --------------------------------------
       original load    19.213k i/100ms
      optimised load    24.709k i/100ms
Calculating -------------------------------------
       original load    191.742k (± 1.6%) i/s -    960.650k in   5.011484s
      optimised load    249.776k (± 1.5%) i/s -      1.260M in   5.046264s

Comparison:
      optimised load:   249775.6 i/s
       original load:   191742.5 i/s - 1.30x  (± 0.00) slower

-- dump --
Warming up --------------------------------------
       original dump    14.885k i/100ms
      optimised dump    21.402k i/100ms
Calculating -------------------------------------
       original dump    148.451k (± 1.7%) i/s -    744.250k in   5.014900s
      optimised dump    212.112k (± 1.2%) i/s -      1.070M in   5.045697s

Comparison:
      optimised dump:   212111.6 i/s
       original dump:   148450.9 i/s - 1.43x  (± 0.00) slower
```
