Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Array vs ArraySeq comparison

Tags:

arrays

scala

This is a bit of a general question but I was wondering if anybody could advise me on what would be advantages of working with Array vs ArraySeq. From what I have seen Array is scala's representation of java Array and there are not too many members in its API whereas ArraySeq seems to contain a much richer API.

like image 245
spydadome Avatar asked Feb 17 '11 11:02

spydadome


3 Answers

There are actually four different classes you could choose from to get mutable array-like functionality.

Array + ArrayOps
WrappedArray
ArraySeq
ArrayBuffer

Array is a plain old Java array. It is by far the best way to go for low-level access to arrays of primitives. There's no overhead. Also it can act like the Scala collections thanks to implicit conversion to ArrayOps, which grabs the underlying array, applies the appropriate method, and, if appropriate, returns a new array. But since ArrayOps is not specialized for primitives, it's slow (as slow as boxing/unboxing always is).

WrappedArray is a plain old Java array, but wrapped in all of Scala's collection goodies. The difference between it and ArrayOps is that WrappedArray returns another WrappedArray--so at least you don't have the overhead of having to re-ArrayOps your Java primitive array over and over again for each operation. It's good to use when you are doing a lot of interop with Java and you need to pass in plain old Java arrays, but on the Scala side you need to manipulate them conveniently.

ArraySeq stores its data in a plain old Java array, but it no longer stores arrays of primitives; everything is an array of objects. This means that primitives get boxed on the way in. That's actually convenient if you want to use the primitives many times; since you've got boxed copies stored, you only have to unbox them, not box and unbox them on every generic operation.

ArrayBuffer acts like an array, but you can add and remove elements from it. If you're going to go all the way to ArraySeq, why not have the added flexibility of changing length while you're at it?

like image 136
Rex Kerr Avatar answered Nov 01 '22 19:11

Rex Kerr


From the scala-lang.org forum:

Array[T] - Benefits: Native, fast - Limitations: Few methods (only apply, update, length), need to know T at compile-time, because Java bytecode represents (char[] different from int[] different from Object[])

ArraySeq[T] (the class formerly known as GenericArray[T]): - Benefits: Still backed by a native Array, don't need to know anything about T at compile-time (new ArraySeq[T] "just works", even if nothing is known about T), full suite of SeqLike methods, subtype of Seq[T] - Limitations: It's backed by an Array[AnyRef], regardless of what T is (if T is primitive, then elements will be boxed/unboxed on their way in or out of the backing Array)


ArraySeq[Any] is much faster than Array[Any] when handling primitives. In any code you have Array[T], where T isn't <: AnyRef, you'll get faster performance out of ArraySeq.

like image 34
Vasil Remeniuk Avatar answered Nov 01 '22 18:11

Vasil Remeniuk


Array is a direct representation of Java's Array, and uses the exact same bytecode on the JVM.

The advantage of Array is that it's the only collection type on the JVM to not undergo type erasure, Arrays are also able to directly hold primitives without boxing, this can make them very fast under some circumstances.

Plus, you get Java's messed up array covariance behaviour. (If you pass e.g. an Array[Int] to some Java class it can be assigned to a variable of type Array[Object] which will then throw an ArrayStoreException on trying to add anything that isn't an int.)

ArraySeq is rarely used nowadays, it's more of a historic artifact from older versions of Scala that treated arrays differently. Seeing as you have to deal with boxing anyway, you're almost certain to find that another collection type is a better fit for your requirements.

Otherwise... Arrays have exactly the same API as ArraySeq, thanks to an implicit conversion from Array to ArrayOps.

Unless you have a specific need for the unique properties of arrays, try to avoid them too. See This Talk at around 19:30 or This Article for an idea of the sort of problems that Arrays can introduce.

After watching that video, it's interesting to note that Scala uses Seq for varargs :)

like image 25
Kevin Wright Avatar answered Nov 01 '22 18:11

Kevin Wright