Является ли конкатенация строк в Scala такой же дорогой, как и в Java?
В Java наиболее распространенной практикой является объединение строк с помощью StringBuilder из-за низкой производительности добавления строк с помощью оператора +. Рекомендуется ли такая же практика для Scala или улучшен язык того, как java выполняет конкатенацию строк?
4 ответа
Scala использует строки Java (java.lang.String
), поэтому его конкатенация строк такая же, как и в Java: в обоих случаях происходит одно и то же. (Время выполнения одинаково, в конце концов.) Существует специальный StringBuilder
класс в Scala, который "предоставляет API, совместимый с java.lang.StringBuilder
"; см. http://www.scala-lang.org/api/2.7.5/scala/StringBuilder.html.
Но с точки зрения "лучших практик", я думаю, что большинство людей, как правило, считают, что лучше писать простой, понятный код, чем максимально эффективный код, за исключением случаев, когда существует реальная проблема производительности или веская причина ожидать ее. +
у оператора на самом деле нет "плохой работы", просто s += "foo"
эквивалентно s = s + "foo"
(т.е. он создает новый String
объект), что означает, что, если вы делаете много конкатенаций с (как выглядит) "одной строкой", вы можете избежать создания ненужных объектов - и многократного повторного копирования более ранних частей из одной строки в другую - используя StringBuilder
вместо String
, Обычно разница не важна. (Конечно, "простой, понятный код" немного противоречив: использование +=
проще, используя StringBuilder
понятнее. Но, тем не менее, решение обычно должно основываться на соображениях написания кода, а не на незначительных соображениях производительности.)
Конкатенация Scalas String работает так же, как и Javas.
val x = 5
"a"+"b"+x+"c"
переводится на
new StringBuilder()).append("ab").append(BoxesRunTime.boxToInteger(x)).append("c").toString()
StringBuilder это scala.collection.mutable.StringBuilder. Вот почему значение, добавляемое к StringBuilder, упаковывается компилятором.
Вы можете проверить поведение, декомпилировав байт-код с помощью javap.
Я хочу добавить: если у вас есть последовательность строк, то уже есть метод для создания новой строки из них (все элементы, объединенные). Это называется mkString
,
Пример: ( http://ideone.com/QJhkAG)
val example = Seq("11111", "2222", "333", "444444")
val result = example.mkString
println(result) // prints "111112222333444444"
Скала использует java.lang.String
как тип для строк, поэтому он подчиняется тем же характеристикам.