Home > OS >  Scala : StringBuilder class (append vs =) performance
Scala : StringBuilder class (append vs =) performance

Time:07-08

I was using ' =' in scala for combining the string values using StringBuilder class instance.

StringBuilder class also provides append method that takes string parameter to combine string values.

I could see both the methods in the scala stringbuilder class documentation here .

I was told that = is slower than append while combining multiple string values but I am not able to find any documentation that says it would be slower.

If anyone can give some link to documentation or explanation on why = is slower than append that would help me understand the concept better.

Operation that I am performing or the code is as below:

val sourceAlias = "source"
val destinationAlias = "destination"
val compositeKeys = Array("Id","Name") 
val initialUpdateExpression = new StringBuilder("")
for (key <- compositeKeys) {
    initialUpdateExpression   = s"$sourceAlias.$key = $destinationAlias.$key and "
}
initialUpdateExpression   = s"$sourceAlias.Valid = $destinationAlias.Valid"
val updateExpression = initialUpdateExpression.toString() 

CodePudding user response:

There is no difference. But you should not be using StringBuilder to begin with. Mutable structures and vars are evil, you should pretend they do not exist at all, at least until you acquire enough command of the language to be able to identify the 0.1% of use cases where they are actually necessary.

val updateExpression = Seq("Id", "Name", "Valid")
   .map { key => s"source.$key = destination.$key") }
   .mkString(" and ")

CodePudding user response:

They seem to be the same, as far as I can tell directly from the code in StringBuider.scala for Scala 2.13.8.

= looks like this:

  /** Alias for `addAll` */
  def   = (s: String): this.type = addAll(s)

which calls:

  /** Overloaded version of `addAll` that takes a string */
  def addAll(s: String): this.type = { underlying.append(s); this }

That in the end, calls:

@Override
@HotSpotIntrinsicCandidate
public StringBuilder append(String str) {
    super.append(str);
    return this;
}

Whereas, append is overloaded, but assuming you want the String version:

  /** Appends the given String to this sequence.
    *
    *  @param  s   a String.
    *  @return     this StringBuilder.
    */
  def append(s: String): StringBuilder = {
    underlying append s
    this
  }

Which in turn, calls:

@Override
@HotSpotIntrinsicCandidate
public StringBuilder append(String str) {
    super.append(str);
    return this;
}

Which is exactly the same code, as = calls. So no, they should have the same performance for your particular use case. I also tried decompiling an example with both method calls, and I did not see any difference between them.

EDIT: Perhaps you might been told about better performance when combining multiple string values in the same append versus using String concatenation . For example:

  sb.append("some"   "thing")
  sb.append("some").append("thing")

The second line is slightly more efficient, since in the first one you create an additional String and an additional unnamed StringBuilder. If this is the case, check this post for clarification on this matter.

  • Related