A little ObjectSpace
exploration gives:
n = 1
GC.disable
a = ObjectSpace.count_objects[:T_STRING]
strings = {}
ObjectSpace.each_object(String) { |s| strings[s.object_id] = s }
n.times { ENV["HOME"] }
b = ObjectSpace.count_objects[:T_STRING]
p a => b
p (b-a)/n.to_f
new_strings = ObjectSpace.each_object(String).reject {|s| strings.key? s.object_id }
p new_strings
p new_strings.size
ObjectSpace.count_objects
seems unreliable in this case, sometimes the number of T_STRING
is less after invocations of ENV["HOME"]
yet the GC is supposed to be disabled.
The difference using ObjectSpace.each_object
give us the 3 String:
["/home/me", "UTF-8", "HOME"]
I am a bit concerned about the "UTF-8"
String created.
"HOME"
is created each time, and could be avoided by assigning it to a variable.
After all, the compiler is not supposed to know ENV[]
is not modifying its argument,
and there is no clue the String
should be immutable.
(detection of literal .freeze
should help, but will anyone do ENV["HOME".freeze]
?
Anyway real code would likely not invoke ENV[var]
many times for the same var)