Issue #9080 has been updated by Eregon (Benoit Daloze).


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)

----------------------------------------
Bug #9080: ENV[key] produces three objects
https://bugs.ruby-lang.org/issues/9080#change-42752

Author: wycats (Yehuda Katz)
Status: Open
Priority: Normal
Assignee: ko1 (Koichi Sasada)
Category: 
Target version: 
ruby -v: ruby 2.0.0p343 (2013-10-31) [x86_64-linux]
Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN


This code:

  ENV["HOME"]

allocates three T_STRING according to ObjectSpace.count_objects. Unless I'm missing something, it should only need to allocate one string.


-- 
http://bugs.ruby-lang.org/