Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Snapshot for Scala 2.12.0-M3? #12

Open
andrewdbate opened this issue Mar 13, 2016 · 8 comments
Open

Snapshot for Scala 2.12.0-M3? #12

andrewdbate opened this issue Mar 13, 2016 · 8 comments

Comments

@andrewdbate
Copy link

Could you please release a snapshot for Scala 2.12.0-M3?

Many thanks!

@Daenyth
Copy link

Daenyth commented Sep 13, 2016

Bump.

Is this project still alive?

@fdietze
Copy link

fdietze commented Aug 11, 2017

I just tried to run tests with latest Scala 2.12.3: #13 (one test fails)

Any idea?

@kamilkloch
Copy link

Any chance for a 2.12 release? It happens to be a blocker for ND4S...
https://github.com/deeplearning4j/deeplearning4j/blob/acd2bc9679e384825b24a1e891027a8ad6f12095/nd4s/build.sbt#L28

@fdietze
Copy link

fdietze commented Nov 26, 2018

You can use jitpack with the port from #13:

addCompilerPlugin("com.github.fdietze" % "scalaxy-streams" % "2.12-819f13722a-1")

@kamilkloch
Copy link

Thanks, @fdietze! Not though sure if ND4S will swallow this one ;)

@andrewdbate
Copy link
Author

andrewdbate commented Nov 26, 2018

@kamilkloch I would recommend that ND4S try to migrate away from scalaxy-streams at this point. I used to use scalaxy-streams in many projects, but it was always a blocker when upgrading to a new version of the Scala language.

When I had to remove scalaxy-streams from my projects, there were two choices:

  1. Replace the scalaxy macros with normal language constructs (e.g. while loops).
  2. Replace the scalaxy macros with your own macros, which you can maintain from one release of Scala to another.

What I found was that most of the time option (1) was the simplest option, and the odd while loop really wasn't that bad after all.

However, for one project in particular, it was worth going with option (2) because:

  • I used the macros in many places and it would make the code ugly to the point where the logic would be significantly obscured if I were to replace the scalaxy macros with the code generated by the scalaxy macros, and
  • I only used a few different scalaxy macros, in similar ways over and over again.

Here are some macros that I wrote to replace the use of some of the scalaxy macros:
https://github.com/andrewdbate/Sequoia/blob/master/reasoner-macros/src/main/scala/com/sequoiareasoner/arrayops/package.scala

@fdietze
Copy link

fdietze commented Nov 28, 2018

I found that you could actually get VERY far without macros. Let me explain.

I think that the @inline annotation of Scala is very undervalued in what can be done with it.

Sadly, this currently only works in ScalaJS, but I think these optimizations would be very important for the JVM as well.

Most people only know @inline for this simple use-case:

@inline def square(x:Double) = x * x
println(square(a + b))

And most of the time the question is: Is inline here worth it, or will the compiler and jit know better?

But there are other more powerful uses of @inline.

When you write

implicit final class RichArray[T](val array:Array[T]) extends AnyVal {
  @inline def foreachIndexAndElement(f: (Int,T) => Unit): Unit = {
    val n = array.length
    var i = 0

    while(i < n ) {
      f(i, array(i))
      i += 1
    }
  }
}

and then you can use it as:

val array = Array(1,2,3)
array.foreachIndexAndElement { (i,elem) =>
    println(s"$i: $elem")
}

The @inline annotation here will tell the compiler to actually unwrap and completely inline the passed lambda function.

val n = array.length
var i = 0

while(i < n ) {
  println(s"$i: ${array(i)}")
  i += 1
}

Another use-case I just found is that you can annotate classes with @inline:

(see also https://odersky.github.io/sips//pending/inline-classes.html)

@inline final case class Vec2(x: Double, y: Double) {
  @inline def +(that: Vec2) = Vec2(this.x + that.x, this.y + that.y)
}

The compiler tries hard to avoid allocations of Vec2. Similarly to a value class, but with more parameters allowed. This allows for zero-overhead-abstractions that I didn't think were possible in Scala:

object InterleavedVec2Array {
  @inline def create(n:Int): InterleavedVec2Array = new InterleavedVec2Array(new Array[Double](n*2))
}

@inline final class InterleavedVec2Array(val interleaved:Array[Double]) {
  @inline def apply(i:Int) = new Vec2(interleaved(i*2), interleaved(i*2+1))
  @inline def update(i:Int, newVec:Vec2) = {
    interleaved(i*2  ) = newVec.x
    interleaved(i*2+1) = newVec.y
  }
}

This allows to write high-level code with memory access patterns that are cache-optimized and avoid unnecessary heap allocations.

As I'm working a lot with scala-js performance, so I moved my array-helpers to a library: https://github.com/fdietze/flatland (now I realize that these are only helpful in scalaJS)

I think these are important real-world performance abstractions that should also work in JVM/native scala. Maybe the relevant parts of the scala-js optimizer can be moved to the core scala compiler? Or is this impossible because scalaJS has better assumptions about the code?

(old 2015 reference, that the scalaJS compiler has a different optimizer: scala-js/scala-js#1588 (comment))

@sjrd could you tell us what the current state of these kinds of optimizations is? Is this maybe already addressed in 2.13 or dotty?

@sjrd
Copy link

sjrd commented Nov 28, 2018

Scala.js and Scala Native have a huge inherent advantage compared to Scala/JVM in terms of optimizations: they assume a closed world, whereas the JVM optimizer always has to deal with class loading and separate compilation.

But if you're willing to sacrifice hot-swapping of .jars and separate compilation, you can enable all the crazy optimizations in Scala 2.12, and it will get close to what Scala.js can do (not @inline classes).
https://developer.lightbend.com/blog/2018-11-01-the-scala-2.12-2.13-inliner-and-optimizer/index.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants