Project

General

Profile

Actions

Bug #17209

closed

String#slice allocates Range object in ruby 3.0.0preview1

Added by bruno.escherl@xing.com (Bruno Escherl) over 3 years ago. Updated over 3 years ago.

Status:
Closed
Target version:
-
ruby -v:
ruby 3.0.0preview1 (2020-09-25 master 0096d2b895) [x86_64-darwin19]
[ruby-core:100262]

Description

While trying to optimise a use case, where I need to get parts of a string extracted, ignoring a constant length prefix, I noticed that ruby 3.0.0preview1 allocates an additional Range object for String#slice, that ruby 2.7.1 didn't allocate.

Test script using memory_profiler gem:

require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'
  gem 'memory_profiler'
end

string = 'const:prefix:and:the:rest'

MemoryProfiler.report do
  10000.times do
    string.slice(13..-1)
  end
end.pretty_print

Output for ruby 3.0.0preview1

Total allocated: 800000 bytes (20000 objects)
Total retained:  0 bytes (0 objects)

allocated memory by gem
-----------------------------------
    800000  other

allocated memory by file
-----------------------------------
    800000  profile_string_slice.rb

allocated memory by location
-----------------------------------
    800000  profile_string_slice.rb:12

allocated memory by class
-----------------------------------
    400000  Range
    400000  String

allocated objects by gem
-----------------------------------
     20000  other

allocated objects by file
-----------------------------------
     20000  profile_string_slice.rb

allocated objects by location
-----------------------------------
     20000  profile_string_slice.rb:12

allocated objects by class
-----------------------------------
     10000  Range
     10000  String

Output for ruby 2.7.1

Total allocated: 400000 bytes (10000 objects)
Total retained:  0 bytes (0 objects)

allocated memory by gem
-----------------------------------
    400000  other

allocated memory by file
-----------------------------------
    400000  profile_string_slice.rb

allocated memory by location
-----------------------------------
    400000  profile_string_slice.rb:12

allocated memory by class
-----------------------------------
    400000  String

allocated objects by gem
-----------------------------------
     10000  other

allocated objects by file
-----------------------------------
     10000  profile_string_slice.rb

allocated objects by location
-----------------------------------
     10000  profile_string_slice.rb:12

allocated objects by class
-----------------------------------
     10000  String

Is this a regression in ruby 3 or something that memory_profiler doesn't record correctly in 2.7?

Updated by mame (Yusuke Endoh) over 3 years ago

  • Status changed from Open to Assigned
  • Assignee set to ko1 (Koichi Sasada)

The optimization has been disabled temporarily because of Ractor.

https://github.com/ruby/ruby/blob/c881678cd75432f47903a5d1d8b86a7a723cb023/compile.c#L8647-L8648

        // TODO: Ractor can not use cached Range objects
	if (0 && optimizable_range_item_p(b) && optimizable_range_item_p(e)) {

As #15504 was accepted, now can we remove this restriction? @ko1 (Koichi Sasada)

Updated by ko1 (Koichi Sasada) over 3 years ago

  • Status changed from Assigned to Closed
Actions

Also available in: Atom PDF

Like0
Like0Like0