Are ruby ​​string literals cached?

I have the code for this form:

class String
  def is_jpg?
    start_with? "\xFF\xD8\xFF".b
  end
end

String # b returns a copy of the string, but is encoded as ASCII-8BIT. My question

Is the Ruby interpreter smart enough to cache the result of b () in the above example, so that calls to this method for different instances of String should not create a new copy of "\ xFF \ xD8 \ xFF" every time? Or should I do something like:

class String
  JPG_SIGNATURE = "\xFF\xD8\xFF".b
  def is_jpg?
    start_with? JPG_SIGNATURE
  end
end

The answer depends on the version of ruby ​​and / or the interpreter? I am using MRI 2.2.x soon to be 2.3.x.

+4
source share
3 answers

No, by default Ruby will create a new copy String, but you can prevent this by freezingString

class String
  def is_jpg?
    start_with? "\xFF\xD8\xFF".freeze.b
  end
end

or

class String
  JPG_SIGNATURE = "\xFF\xD8\xFF".freeze.b
  def is_jpg?
    start_with? JPG_SIGNATURE
  end
end

. http://blog.honeybadger.io/when-to-use-freeze-and-frozen-in-ruby/

+3

:

Ruby , b()

. Ruby. .

def foo
  x = 'foo'
  puts x.object_id
end

> foo
70281000268840
> foo
70281000264340

- . . .

String::JPG_SIGNATURE = "\xFF\xD8\xFF".b

: kcdragon. freeze , !

+1

: , .

            user     system      total        real
normal  0.270000   0.000000   0.270000 (  0.272052)
const   0.160000   0.000000   0.160000 (  0.155427)
freeze  0.240000   0.000000   0.240000 (  0.238170)

It seems that on my machine using the official Ruby virtual machine, the string is not cached, since using a constant provides speed acceleration. Freezing the string also provides a boost, but substantially less.

Note that I had to call the method millions of times to see any noticeable difference. I would classify this as premature optimization if your profiling did not show that this particular method is a serious bottleneck.

0
source

Source: https://habr.com/ru/post/1653046/


All Articles