什麼是 frozen_string_literal?
by Aaron • 10/23/2024, 1:11:32 PM

在使用 RUBOCOP 會發現儲存的時候 會在當前檔案最上方加一個 Magic Comment, # frozen_string_literal: true
, 到底這個 comment 有什麼作用呢?
加上 frozen_string_literal: true/false 會有什麼差異 ?
其實就只是 string.freeze 的語法糖而已, 加上之後整個檔案的 string 就會變成 freeze 的狀態
# frozen_string_literal: true
str = "Hello World"
str[1] = "h"
pp str
# Traceback (most recent call last):
# 1: from test.rb:14:in `<main>'
# test.rb:14:in `[]=': can't modify frozen String: "Hello World" (FrozenError)
相當於
str = "Hello World".freeze
str[1] = "h"
pp str
為什麼要 freeze sting 呢? 什麼時候應該要加 frozen_string_literal: true ?
- 可以減少 Garbage
start = GC.stat[:total_allocated_objects]
100_000.times { "test".freeze.dup }
finish = GC.stat[:total_allocated_objects]
puts "With frozen: #{finish - start}"
# With frozen: 100001
start = GC.stat[:total_allocated_objects]
100_000.times { "test".dup }
finish = GC.stat[:total_allocated_objects]
puts "Without frozen: #{finish - start}"
# Without frozen: 200001
- 這樣在當前的作用域 string 的行為會跟 symbol 接近
# frozen_string_literal: true
foo = "aaron"
bar = "aaron"
pp foo.object_id
# 60
pp bar.object_id
# 60
Benchmark.bm(15) do |x|
x.report("Without frozen: ") do
1_000_000_000.times { "aaron".dup }
end
x.report("With frozen") do
1_000_000_000.times {"aaron".freeze.dup}
end
end
# user system total real
# Without frozen: 108.935660 3.775396 112.711056 (113.095394)
# With frozen 90.101091 1.988797 92.089888 ( 92.543350)