What is the difference between scala.collections.mutable.ArrayBuilder and scala.collections.mutable.ArrayBuffer? If, for instance, I need to build an Array[Int], which is preferrable to use? Is there any perfomance difference, like in java.lang.StringBuffer and java.lang.StringBuilder?
2 Answers
ArrayBuilder is a Builder, and builders are meant to be used to construct other collections by adding elements to them. Builders are not usually meant to be used directly in client code.
ArrayBuffer is a Buffer and Seq -- buffers are sequences to which you can efficiently append elements. Sequences come with a lot of auxiliary operations.
You probably need an ArrayBuffer. It is meant to be used as an alternative to the ArrayList in Java. The ArrayBuffer class is a fully-powered sequence collections with all the bulk data operations like foreach, map, filter, zip and friends, unlike ArrayBuilder which is equipped only with += to add elements and result to obtain the array at the end.
One place where you might prefer an ArrayBuilder is when you are instantiating it for a primitive type like Int and you care about performance. In this case the ArrayBuilder variants are specialized for different primitive types and hold an underlying array of a proper primitive type, whereas an ArrayBuffer always holds an object array underneath -- every primitive you add to it undergoes boxing.
To instantiate an array buffer:
new ArrayBuffer[Int] // gives you an array buffer that will hold boxed integers
To instantiate an array builder:
new ArrayBuilder.ofInt // gives you a manually specialized array builder that will hold real primitives
3 Comments
Builder are (semi-) internal classes meant for those writing new collections classes (whether as part of the standard library or extensions to it).ArrayBuilder to get an appropriate array type back. If you use ArrayBuffer, you can still play tricks to get the array out of it, but it will have the type Object[] from the Java point of view, that is, Array[AnyRef] in Scala terms.I timed it and building an array with ArrayBuilder is noticeably faster:
With ArrayBuffer:
real 0m40.348s
user 0m29.544s
sys 0m1.017s
With Array Builder:
real 0m8.392s
user 0m4.769s
sys 0m0.330s
My code:
import scala.collection.mutable.{ArrayBuffer, ArrayBuilder}
object MyObject {
def main(args: Array[String]) {
for (i <- 0 until 100) {
arrayBuilderMade
// or arrayBufferMade
}
}
def arrayBufferMade {
var aBuffer = new ArrayBuffer[Int]()
for (i <- 0 until 1000000) {
aBuffer += i
}
println(aBuffer.toArray.length)
}
def arrayBuilderMade {
var aBuilder = new ArrayBuilder.ofInt
for (i <- 0 until 1000000) {
aBuilder += i
}
println(aBuilder.result.length)
}
}
And
time scala my_code.scala
1 Comment
String). Boxing/unboxing of Int takes its toll.