Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: Optimizer
    • Labels:
      None

      Description

      Quoting from https://groups.google.com/d/topic/scala-internals/5oRYBYBUqMY/discussion

      When you create a collection, a lot of unnecessary work is done.

      Quoting from https://groups.google.com/d/msg/scala-internals/5oRYBYBUqMY/aq93-oBpaukJ

      I think there's a middle ground between what we have now and macro/builtin compiler support. This reminds me an idea I had (and Miguel also mentioned to me) of early inlining. The current state of affairs is that code with foreach call like List(1,2,3) foreach println we first expand lambda to a class, we typecheck everything and generate lots of trees, then icode and only then we realize (if we are lucky) that we can inline foreach implementation, inline apply of a closure and throw away the whole class we generate for the closure. That's a huge amount of wasted work.

      Quoting from The Scala Compiler Corner, about "early inlining"

      1. 2012-07-03: GC-savvy Closure conversion,
        http://lamp.epfl.ch/~magarcia/ScalaCompilerCornerReloaded/2012Q3/2012-07-01-GC-savvy-Closure-conversion.pdf
      2. 2011-11-22: Just trying to generate faster code faster under -optimise
        http://lamp.epfl.ch/~magarcia/ScalaNET/slides/2011-11-22-BetterInlining.pdf

      Many of these performance problems can go away with MethodHandles and invokedynamic. Therefore this bug should be broken up into pre-JDK7 and JDK7 versions.

        Issue Links

          Activity

          Hide
          Miguel Garcia added a comment -

          Quoting from https://groups.google.com/d/topic/scala-internals/5oRYBYBUqMY/discussion

          The cases of particular interest to me are List and Array.

          • List(1, 2, 3) leads to approximately this:
              val arr = new Array[Int](3)
              arr(0) = 1
              arr(1) = 2
              arr(2) = 3
              val wrapped = new WrappedArray(arr)
              List.apply(wrapped) 
              val cbf = implicitly[CanBuildFrom[...]]
              val builder = cbf() // new ListBuffer[Int]
              builder ++= wrapped
              builder.result
            

            When it could be done like this:

              new ::(1, new ::(2, new ::(3, Nil)))
            
          • Array(1, 2, 3) leads to approximately this:
              val arr = new Array[Int](3)
              arr(0) = 1
              arr(1) = 2
              arr(2) = 3
              // Hey, stop right there! Scala, stop! Oh no...
              val wrapped = new WrappedArray(arr)
              Array.apply(wrapped) 
              val arr2 = new Array[Int](wrapped.length)
              var i = 0
              // throw in a closure and a boxing trip through Seq#foreach
              for (x <- wrapped.iterator) { arr2(i) = x; i += 1 } 
              arr2
            
          Show
          Miguel Garcia added a comment - Quoting from https://groups.google.com/d/topic/scala-internals/5oRYBYBUqMY/discussion The cases of particular interest to me are List and Array. List(1, 2, 3) leads to approximately this: val arr = new Array[Int](3) arr(0) = 1 arr(1) = 2 arr(2) = 3 val wrapped = new WrappedArray(arr) List.apply(wrapped) val cbf = implicitly[CanBuildFrom[...]] val builder = cbf() // new ListBuffer[Int] builder ++= wrapped builder.result When it could be done like this: new ::(1, new ::(2, new ::(3, Nil))) Array(1, 2, 3) leads to approximately this: val arr = new Array[Int](3) arr(0) = 1 arr(1) = 2 arr(2) = 3 // Hey, stop right there! Scala, stop! Oh no... val wrapped = new WrappedArray(arr) Array.apply(wrapped) val arr2 = new Array[Int](wrapped.length) var i = 0 // throw in a closure and a boxing trip through Seq#foreach for (x <- wrapped.iterator) { arr2(i) = x; i += 1 } arr2
          Hide
          Jason Zaugg added a comment -

          Primitive array creation using Array.apply has now been hand-optimized in Cleanup, as was already done for reference arrays: https://github.com/scala/scala/commit/8265175e

          Show
          Jason Zaugg added a comment - Primitive array creation using Array.apply has now been hand-optimized in Cleanup , as was already done for reference arrays: https://github.com/scala/scala/commit/8265175e

            People

            • Assignee:
              Unassigned
              Reporter:
              Miguel Garcia
            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:

                Development