понедельник, 10 марта 2008 г.

Ruby: str += "s" vs. str << "s"

Вообще довольно тривиальная вещь, но для меня она явилась некоторой неожиданностью.

Возможно из-за того, что последние 3 года я все время писал программы на .net я как-то привык к тому, что строки являются immutable. Соответственно чтобы изменить строку надо написать что то вроде этого:

string str = "first";
str += "second";

Этот же подход я по привычке стал использовать в ruby (1.8), но оказалось что это очень, очень медленно и гораздо быстрее выполняется конкатенация строк так:

str = "first"
str << "second"

Вот тест:

require 'benchmark'
include Benchmark

str1, str2 = "", ""
bm(6) do |x|
x.report("<<") { 100000.times { str1 << "1" } }
x.report("+=") { 100000.times { str2 += "1" } }
end

Результаты такие:

user system total real
<< 0.094000 0.000000 0.094000 ( 0.094000)
+= 9.125000 0.000000 9.125000 ( 9.125000)

То есть "<<" работает примерно в 100 раз быстрее. Видимо из-за того что не создает новых объектов.

2 комментария:

Unknown комментирует...

+= для строк - это же code smells

В Java для такой операции используются StringBuilder/StringBuffer, так же как в .net ?

p.s.
emutable = immutable

Alex Ilin комментирует...

Привет Дим :) Спасибо за исправление.

c# код илюстрирует, что строка immutable, а "+=" гораздо выразительнее об этом говорит чем StringBuilder.Append.