>> > Freezing string constants does have some performance benefits, but you're starting to get that for free in later ruby versions.
>>
>> Because of what changes?
>
> 2.1 deduplicates string literals in source (but strings still get
> created).
So basically there will be a shared string buffer but still individual
instances, i.e.
def f(a)
"foo" + a + "foo"
end
in Ruby there were two buffers and each String literal would create a
new instance. In 2.1 there is just one buffer and still every literal
creates a new instance for every evaluation.
Correct.
If I understand http://rkh.im/ruby-2.1 properly String instance
creation can be avoided by using the "freeze" modifier:
def f(a)
"foo"f + a + "foo"f
end
We dropped "f", but ".freeze" is equivalent for compatibility with <=2.0
"foo".freeze + a + "foo".freeze
No new "foo" strings created.
Still, with the unfrozen String there is only a space gain and no
performance gain, correct?
Right, since large strings are copy-on-write.
> 2.2 will also reuses frozen strings for hash["lit"] and hash["lit"]=,
> so no new strings are created for common hash get/set ops.
> (r44551 + a few followup fixes)
How does that work? If I understand the diffs [1] properly then the
decision is made at parse time and it seems to me that it is done for
all # that fit the bill. Is that correct?
At parse time, we change the instruction from opt_a* to opt_a*_with
if we detect #["lit"] or #["lit"]=. #[non_lit] calls still become
opt_a* instructions.
At runtime, the new opt_a*_with instructions allow us to avoid
String instance creation if the receiver is a hash.
···
Robert Klemme <shortcutter@googlemail.com> wrote:
On Tue, Apr 22, 2014 at 12:11 PM, Eric Wong <normalperson@yhbt.net> wrote:
> Robert Klemme <shortcutter@googlemail.com> wrote:
>> On Mon, Apr 21, 2014 at 9:14 PM, Ryan Davis <ryand-ruby@zenspider.com> wrote:
[1] https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/44551/diff/