rorygraves / scalac_perf

The Scala programming language
http://www.scala-lang.org/
16 stars 3 forks source link

Arrayops repr #23

Closed mkeskells closed 6 years ago

mkeskells commented 7 years ago

seems inefficient

as repr is a def ( and not stable?) def :+[B >: T: ClassTag](elem: B): Array[B] = { val result = Array.ofDim[B](repr.length + 1) Array.copy(repr, 0, result, 0, repr.length) result(repr.length) = elem result }

// access flags 0x1009 public static synthetic $colon$plus$(Lscala/collection/mutable/ArrayOps;Ljava/lang/Object;Lscala/reflect/ClassTag;)Ljava/lang/Object; // parameter final synthetic $this // parameter final elem // parameter final evidence$2 L0 LINENUMBER 66 L0 ALOAD 0 ALOAD 1 ALOAD 2 INVOKESPECIAL scala/collection/mutable/ArrayOps.$colon$plus (Ljava/lang/Object;Lscala/reflect/ClassTag;)Ljava/lang/Object; ARETURN L1 LOCALVARIABLE $this Lscala/collection/mutable/ArrayOps; L0 L1 0 LOCALVARIABLE elem Ljava/lang/Object; L0 L1 1 LOCALVARIABLE evidence$2 Lscala/reflect/ClassTag; L0 L1 2 MAXSTACK = 3 MAXLOCALS = 3

// access flags 0x1 // signature <B:Ljava/lang/Object;>(TB;Lscala/reflect/ClassTag<TB;>;)Ljava/lang/Object; // declaration: $colon$plus<B>(B, scala.reflect.ClassTag<B>) public default $colon$plus(Ljava/lang/Object;Lscala/reflect/ClassTag;)Ljava/lang/Object; // parameter final elem // parameter final evidence$2 L0 LINENUMBER 67 L0 GETSTATIC scala/Array$.MODULE$ : Lscala/Array$; GETSTATIC scala/runtime/ScalaRunTime$.MODULE$ : Lscala/runtime/ScalaRunTime$; ALOAD 0 INVOKEINTERFACE scala/collection/mutable/ArrayOps.repr ()Ljava/lang/Object; INVOKEVIRTUAL scala/runtime/ScalaRunTime$.array_length (Ljava/lang/Object;)I ICONST_1 IADD ALOAD 2 INVOKEVIRTUAL scala/Array$.ofDim (ILscala/reflect/ClassTag;)Ljava/lang/Object; L1 ASTORE 3 L2 LINENUMBER 68 L2 GETSTATIC scala/Array$.MODULE$ : Lscala/Array$; ALOAD 0 INVOKEINTERFACE scala/collection/mutable/ArrayOps.repr ()Ljava/lang/Object; ICONST_0 ALOAD 3 ICONST_0 GETSTATIC scala/runtime/ScalaRunTime$.MODULE$ : Lscala/runtime/ScalaRunTime$; ALOAD 0 INVOKEINTERFACE scala/collection/mutable/ArrayOps.repr ()Ljava/lang/Object; INVOKEVIRTUAL scala/runtime/ScalaRunTime$.array_length (Ljava/lang/Object;)I INVOKEVIRTUAL scala/Array$.copy (Ljava/lang/Object;ILjava/lang/Object;II)V L3 LINENUMBER 69 L3 GETSTATIC scala/runtime/ScalaRunTime$.MODULE$ : Lscala/runtime/ScalaRunTime$; ALOAD 3 GETSTATIC scala/runtime/ScalaRunTime$.MODULE$ : Lscala/runtime/ScalaRunTime$; ALOAD 0 INVOKEINTERFACE scala/collection/mutable/ArrayOps.repr ()Ljava/lang/Object; INVOKEVIRTUAL scala/runtime/ScalaRunTime$.array_length (Ljava/lang/Object;)I** ALOAD 1 INVOKEVIRTUAL scala/runtime/ScalaRunTime$.array_update (Ljava/lang/Object;ILjava/lang/Object;)V L4 LINENUMBER 70 L4 ALOAD 3 L5 ARETURN L6 LOCALVARIABLE result Ljava/lang/Object; L1 L5 3 LOCALVARIABLE this Lscala/collection/mutable/ArrayOps; L0 L6 0 LOCALVARIABLE elem Ljava/lang/Object; L0 L6 1 LOCALVARIABLE evidence$2 Lscala/reflect/ClassTag; L0 L6 2 MAXSTACK = 7 MAXLOCALS = 4

ackratos commented 6 years ago

@mkeskells Array is a mutable stuff, repr has to be a def right? As within this :+ function, repr.length is different between before and after call Array.copy.

mkeskells commented 6 years ago

@ackratos length is constant and repr is constant although the content is mutable.

Trivially in this method we could remember the length but we could discuss making length a Val to avoid all of this extra code in this and other similar methods. Need to check the expense though I have not benchmarked it

This method is a poor use of java API imo and could use Array.copyOf probably indirectly ti aviid the unknown types that are known in the implementations

The copy of the array does not affect repr of this just what the result of the method may be viewed as