Issue #19315 has been updated by himura467 (Akito Shitara). I wrote some micro-benchmarks targeting the patterns most affected by `SHARABLE_MIDDLE_SUBSTRING`. Environment: arm64-darwin25. current: https://github.com/himura467/ruby/tree/rstring-raw-ptr-explicit-length-ops Ref: https://github.com/himura467/ruby/tree/19315-eval/19315-eval **Throughput scaling with slice size** On master, slicing from the middle of a large string degrades as the result grows (a full copy is made). On this branch, throughput is nearly constant because no copy occurs. <pre> master (a2b9d6ff3b): parent=20MB, offset=1MB middle slice [1MB, 1KB] 4,885,198 ops/s middle slice [1MB, 10KB] 694,444 ops/s middle slice [1MB, 100KB] 279,791 ops/s middle slice [1MB, 1MB] 55,168 ops/s middle slice [1MB, 10MB] 2,458 ops/s current (c7eace4288): parent=20MB, offset=1MB middle slice [1MB, 1KB] 9,066,183 ops/s middle slice [1MB, 10KB] 10,672,359 ops/s middle slice [1MB, 100KB] 11,441,648 ops/s middle slice [1MB, 1MB] 11,614,402 ops/s middle slice [1MB, 10MB] 11,574,074 ops/s </pre> **Small string slices** <pre> master current slice [0, 1000] (ELTS_SHARED) 4,822,298 11,224,604 ops/s (+2.3x) slice [0, 10000] (ELTS_SHARED) 7,029,877 11,879,306 ops/s (+1.7x) </pre> **Memory sharing** (1000 slices x 100KB from a 10MB parent, naive copy total: 100MB) <pre> master current max RSS 145 MB 30 MB (-80%) peak memory 137 MB 22 MB (-84%) wall time 0.04s 0.03s </pre> **Memory retention risk** As mentioned in #note-7, `ELTS_SHARED` keeps the parent string alive as long as any slice references it. In the worst case, slicing a small portion from a large parent retains the entire parent buffer. <pre> master current live data needed 100 KB 100 KB total live string memory after GC 615 KB 100 MB </pre> Strings small enough to be embedded (less than 999 bytes on 64-bit) are copied into the `RString` struct and do not reference the parent, so this risk does not apply to them. ---------------------------------------- Feature #19315: Lazy substrings in CRuby https://bugs.ruby-lang.org/issues/19315#change-117813 * Author: Eregon (Benoit Daloze) * Status: Open ---------------------------------------- CRuby should implement lazy substrings, i.e., "abcdef"[1..3] must not copy bytes. Currently CRuby only reuse the char* if the substring is until the end of the buffer. But it should also work wherever the substring starts and ends. Yes, it means RSTRING_PTR() might need to allocate to \0-terminate, so be it, it's worth it. There is already code for this (`SHARABLE_MIDDLE_SUBSTRING`), but it's disabled by default and `RSTRING_PTR()` needs to be changed to deal with this. It seems a good idea to introduce a variant of `RSTRING_PTR` which doesn't guarantee \0-termination, so such callers can then use the existing bytes always without copy. There are countless workarounds for this missing optimization, all not worth it with lazy substring and all less readable: * https://bugs.ruby-lang.org/issues/19314 * https://bugs.ruby-lang.org/issues/18598#note-3 * https://github.com/ruby/net-protocol/pull/14 * Manual lazy substrings which track string + index + length * More but I don't remember all now, feel free to comment or link more urls/tickets. -- https://bugs.ruby-lang.org/