Project

General

Profile

Bug #14900

Updated by janko (Janko Marohnić) over 1 year ago

When executing `String#byteslice` with a range, I noticed that sometimes the original string is allocated again. When I run the following script: 

 ~~~ ruby 
 require "objspace" 

 string = "a" * 100_000 

 GC.start 
 GC.disable 
 generation = GC.count 

 ObjectSpace.trace_object_allocations do 
   string.byteslice(50_000..-1) 

   ObjectSpace.each_object(String) do |string| 
     p string.bytesize if ObjectSpace.allocation_generation(string) == generation 
   end 
 end 
 ~~~ 

 it outputs 

 ~~~ 
 50000 
 100000 
 6 
 5 
 ~~~ 

 The one with 50000 bytes is the result of `String#byteslice`, but the one with 100000 bytes is the duplicated original string. I expected only the result of `String#byteslice` to be amongst new allocations. 

 If instead of the last 50000 bytes I slice the *first* 50000 bytes, the extra duplication doesn't occur. 

 ~~~ ruby 
 # ... 
   string.byteslice(0, 50_000) 
 # ... 
 ~~~ 

 ~~~ 
 50000 
 5 
 ~~~ 

 It's definitely ok if the implementation of `String#bytesize` allocates extra strings as part of the implementation, but it would be nice if they were deallocated before returning the result. 

 EDIT: It seems that `String#slice` has the same issue.

Back