ruby-changes:39089
From: normal <ko1@a...>
Date: Tue, 7 Jul 2015 04:46:06 +0900 (JST)
Subject: [ruby-changes:39089] normal:r51170 (trunk): string.c: ensure String#freeze resizes internal buffer
normal 2015-07-07 04:45:02 +0900 (Tue, 07 Jul 2015) New Revision: 51170 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=51170 Log: string.c: ensure String#freeze resizes internal buffer rb_str_freeze may resize oversized buffers to save memory, so favor it over rb_obj_freeze. This is useful because IO methods do not prematurely shrink buffers, as they are likely to be overwritten with full data. * string.c (Init_String): use rb_str_freeze for String#freeze Modified files: trunk/ChangeLog trunk/string.c trunk/test/ruby/test_optimization.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 51169) +++ ChangeLog (revision 51170) @@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Tue Jul 7 04:42:25 2015 Eric Wong <e@8...> + + * string.c (Init_String): use rb_str_freeze for String#freeze + to resize internal buffer + [ruby-core:69870] [Feature #11330] + Tue Jul 7 04:12:32 2015 Koichi Sasada <ko1@a...> * vm.c (vm_define_method): remove an unused local variable. Index: string.c =================================================================== --- string.c (revision 51169) +++ string.c (revision 51170) @@ -9150,7 +9150,7 @@ Init_String(void) https://github.com/ruby/ruby/blob/trunk/string.c#L9150 rb_define_method(rb_cString, "byteslice", rb_str_byteslice, -1); rb_define_method(rb_cString, "scrub", str_scrub, -1); rb_define_method(rb_cString, "scrub!", str_scrub_bang, -1); - rb_define_method(rb_cString, "freeze", rb_obj_freeze, 0); + rb_define_method(rb_cString, "freeze", rb_str_freeze, 0); rb_define_method(rb_cString, "to_i", rb_str_to_i, -1); rb_define_method(rb_cString, "to_f", rb_str_to_f, 0); Index: test/ruby/test_optimization.rb =================================================================== --- test/ruby/test_optimization.rb (revision 51169) +++ test/ruby/test_optimization.rb (revision 51170) @@ -1,4 +1,5 @@ https://github.com/ruby/ruby/blob/trunk/test/ruby/test_optimization.rb#L1 require 'test/unit' +require 'objspace' class TestRubyOptimization < Test::Unit::TestCase @@ -122,6 +123,24 @@ class TestRubyOptimization < Test::Unit: https://github.com/ruby/ruby/blob/trunk/test/ruby/test_optimization.rb#L123 assert_redefine_method('String', 'freeze', 'assert_nil "foo".freeze') end + def test_string_freeze_saves_memory + n = 16384 + data = '.'.freeze + r, w = IO.pipe + w.write data + + s = r.readpartial(n, '') + assert_operator ObjectSpace.memsize_of(s), :>=, n, + 'IO buffer NOT resized prematurely because will likely be reused' + + s.freeze + assert_equal ObjectSpace.memsize_of(data), ObjectSpace.memsize_of(s), + 'buffer resized on freeze since it cannot be written to again' + ensure + r.close if r + w.close if w + end + def test_string_eq_neq %w(== !=).each do |m| assert_redefine_method('String', m, <<-end) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/