Which way to construct Seq[T]
instance is better?
Seq.apply
List.apply
:: Nil
:: Nil
is the fastest.
Seq.apply
is faster than List.apply
.
-
Seq.apply
def apply[A](elems: A*): CC[A] = { if (elems.isEmpty) empty[A] else { val b = newBuilder[A] b ++= elems b.result() } }
-
List.apply
override def apply[A](xs: A*): List[A] = xs.toList
-
xs.toList
deligates toto[List]
def to[Col[_]](implicit cbf: CanBuildFrom[Nothing, A, Col[A @uV]]): Col[A @uV] = { val b = cbf() b ++= seq b.result() }
-
-
:: Nil
def ::[B >: A] (x: B): List[B] = new scala.collection.immutable.::(x, this)
this
isNil
.
These implementations show that :: Nil
just creates new ::
class instance with providing Nil
as a tail and an argument to head.
Others, Seq.apply
and List.apply
delegate to ++=
of Builder
, to be accurate, Growable
.
It runs pattern-match and invokes a function to add each element to a ListBuffer
, therefore, it's a little slower than :: Nil
.
These byte-code shows only :: Nil
does not create NEWARRAY
.
// access flags 0x1
// signature ()Lscala/collection/Seq<Ljava/lang/Object;>;
// declaration: scala.collection.Seq<java.lang.Object> seq()
public seq()Lscala/collection/Seq;
@Lorg/openjdk/jmh/annotations/Benchmark;()
@Lorg/openjdk/jmh/annotations/BenchmarkMode;(value={Lorg/openjdk/jmh/annotations/Mode;.Throughput})
L0
LINENUMBER 27 L0
GETSTATIC scala/collection/Seq$.MODULE$ : Lscala/collection/Seq$;
GETSTATIC scala/Predef$.MODULE$ : Lscala/Predef$;
ICONST_1
NEWARRAY T_INT
DUP
ICONST_0
ALOAD 0
INVOKEVIRTUAL net/petitviolet/sandbox/perf/SeqOrList.NUM ()I
IASTORE
INVOKEVIRTUAL scala/Predef$.wrapIntArray ([I)Lscala/collection/mutable/WrappedArray;
INVOKEVIRTUAL scala/collection/Seq$.apply (Lscala/collection/Seq;)Lscala/collection/GenTraversable;
CHECKCAST scala/collection/Seq
ARETURN
L1
LOCALVARIABLE this Lnet/petitviolet/sandbox/perf/SeqOrList; L0 L1 0
MAXSTACK = 6
MAXLOCALS = 1
// access flags 0x1
// signature ()Lscala/collection/Seq<Ljava/lang/Object;>;
// declaration: scala.collection.Seq<java.lang.Object> listApply()
public listApply()Lscala/collection/Seq;
@Lorg/openjdk/jmh/annotations/Benchmark;()
@Lorg/openjdk/jmh/annotations/BenchmarkMode;(value={Lorg/openjdk/jmh/annotations/Mode;.Throughput})
L0
LINENUMBER 33 L0
GETSTATIC scala/collection/immutable/List$.MODULE$ : Lscala/collection/immutable/List$;
GETSTATIC scala/Predef$.MODULE$ : Lscala/Predef$;
ICONST_1
NEWARRAY T_INT
DUP
ICONST_0
ALOAD 0
INVOKEVIRTUAL net/petitviolet/sandbox/perf/SeqOrList.NUM ()I
IASTORE
INVOKEVIRTUAL scala/Predef$.wrapIntArray ([I)Lscala/collection/mutable/WrappedArray;
INVOKEVIRTUAL scala/collection/immutable/List$.apply (Lscala/collection/Seq;)Lscala/collection/immutable/List;
ARETURN
L1
LOCALVARIABLE this Lnet/petitviolet/sandbox/perf/SeqOrList; L0 L1 0
MAXSTACK = 6
MAXLOCALS = 1
// access flags 0x1
// signature ()Lscala/collection/Seq<Ljava/lang/Object;>;
// declaration: scala.collection.Seq<java.lang.Object> listColon()
public listColon()Lscala/collection/Seq;
@Lorg/openjdk/jmh/annotations/Benchmark;()
@Lorg/openjdk/jmh/annotations/BenchmarkMode;(value={Lorg/openjdk/jmh/annotations/Mode;.Throughput})
L0
LINENUMBER 39 L0
ALOAD 0
INVOKEVIRTUAL net/petitviolet/sandbox/perf/SeqOrList.NUM ()I
ISTORE 1
GETSTATIC scala/collection/immutable/Nil$.MODULE$ : Lscala/collection/immutable/Nil$;
ILOAD 1
INVOKESTATIC scala/runtime/BoxesRunTime.boxToInteger (I)Ljava/lang/Integer;
INVOKEVIRTUAL scala/collection/immutable/Nil$.$colon$colon (Ljava/lang/Object;)Lscala/collection/immutable/List;
ARETURN
L1
LOCALVARIABLE this Lnet/petitviolet/sandbox/perf/SeqOrList; L0 L1 0
MAXSTACK = 2
MAXLOCALS = 2