Rubyで定数をfreezeしても高速化はしない

定数をfrozenにしておくと高速化するという記事が公開されていました。 techracho.bpsinc.jp

定数をfreezeしておけばメモリ使用量も少し節約できるので完璧です。

記事には上記のようにあったので、圧縮などを行い確保量を少なくしているのかなと思ったのですが、

[1] pry(main)> ObjectSpace.memsize_of([1, 2, 3])
=> 40
[2] pry(main)> ARRAY = [1, 2, 3].freeze
=> [1, 2, 3]
[3] pry(main)> ObjectSpace.memsize_of(ARRAY)
=> 40

ObjectSpaceで検証してみるとメモリサイズは同じだと言われました🤔 freezeするとメモリアロケーションが削減される というのはどういう意味なのか社内のslackで聞いたみたところ

Rubyコミッターの卜部さんから下記の回答をいただきました。 f:id:kamillle:20200224212919p:plain

ObjectSpaceで検証した通り、freezeではメモリアロケーションは削減できないようですね。 ちなみに写真で紹介されているfreezeでメモリ圧縮する機能はまだ本線にはマージされていないようです。中々メモリアロケーションまで気にしてコードを書くことは少ないですが、早くマージされるといいですね!

github.com

また

frozen_string_literal: true は効果があります(生まれた時からfrozenなら適用できる最適化の箇所がやや広がります)

と書かれいているのは、同じ文字列であればすべて同じobject_idを返すようにして都度都度オブジェクトを生成しないからみたいです。

# frozen_string_literal: true

hoge = 'aaa'
fuga = 'aaa'

# 全部同じobject_id
puts 'aaa'.object_id # => 70240713691900
puts hoge.object_id  # => 70240713691900
puts fuga.object_id  # => 70240713691900