From 14d03b18774976b6622fa406fdabb7d0b060bc9e Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Fri, 7 Jan 2022 01:40:38 +0000 Subject: [PATCH 1/2] Rename fastFor back to cfor --- .../spire/benchmark/CForBenchmark.scala | 0 .../spire/benchmark/FastForBenchmark.scala | 374 ------------------ .../main/scala-2/spire/syntax/Syntax.scala | 49 --- .../scala-3/spire/syntax/CforSyntax.scala | 36 +- .../scala-3/spire/syntax/FastForSyntax.scala | 39 -- .../main/scala-3/spire/syntax/Syntax.scala | 1 - .../spire/syntax/macros/cforMacros.scala | 10 +- .../src/main/scala/spire/syntax/package.scala | 2 - docs/src/main/mdoc/index.md | 10 +- .../src/main/scala/spire/example/kleene.scala | 12 +- .../src/main/scala/spire/example/kmeans.scala | 12 +- .../src/main/scala/spire/example/loops.scala | 6 +- .../main/scala/spire/example/mandelbrot.scala | 4 +- .../scala/spire/example/randomforest.scala | 12 +- .../scala/spire/syntax/FastForSuite.scala | 176 --------- .../scala/spire/syntax/CforSuite.scala | 0 16 files changed, 54 insertions(+), 689 deletions(-) rename benchmark/src/main/{scala-2 => scala}/spire/benchmark/CForBenchmark.scala (100%) delete mode 100644 benchmark/src/main/scala/spire/benchmark/FastForBenchmark.scala delete mode 100644 core/src/main/scala-3/spire/syntax/FastForSyntax.scala delete mode 100644 tests/shared/src/test/scala-3/scala/spire/syntax/FastForSuite.scala rename tests/shared/src/test/{scala-2 => }/scala/spire/syntax/CforSuite.scala (100%) diff --git a/benchmark/src/main/scala-2/spire/benchmark/CForBenchmark.scala b/benchmark/src/main/scala/spire/benchmark/CForBenchmark.scala similarity index 100% rename from benchmark/src/main/scala-2/spire/benchmark/CForBenchmark.scala rename to benchmark/src/main/scala/spire/benchmark/CForBenchmark.scala diff --git a/benchmark/src/main/scala/spire/benchmark/FastForBenchmark.scala b/benchmark/src/main/scala/spire/benchmark/FastForBenchmark.scala deleted file mode 100644 index 06b90ef65..000000000 --- a/benchmark/src/main/scala/spire/benchmark/FastForBenchmark.scala +++ /dev/null @@ -1,374 +0,0 @@ -/* - * **********************************************************************\ - * * Project ** - * * ______ ______ __ ______ ____ ** - * * / ____/ / __ / / / / __ / / __/ (c) 2011-2021 ** - * * / /__ / /_/ / / / / /_/ / / /_ ** - * * /___ / / ____/ / / / __ / / __/ Erik Osheim, Tom Switzer ** - * * ____/ / / / / / / / | | / /__ ** - * * /_____/ /_/ /_/ /_/ |_| /____/ All rights reserved. ** - * * ** - * * Redistribution and use permitted under the MIT license. ** - * * ** - * \*********************************************************************** - */ - -package spire -package benchmark - -import java.util.concurrent.TimeUnit - -import org.openjdk.jmh.annotations._ - -import scala.util.Random -import Random._ - -import spire.syntax.fastFor._ - -import Arrays.init - -@BenchmarkMode(Array(Mode.AverageTime)) -@OutputTimeUnit(TimeUnit.MICROSECONDS) -@State(Scope.Thread) -class FastForBenchmarks { - // @Param(Array("10", "15", "20", "25")) - // @Param(Array("1000", "10000", "100000", "1000000")) - @Param(Array("1000000")) - var size: Int = 0 - - var arr: Array[Long] = null - - @Setup - def setup(): Unit = { - arr = init(size)(scala.math.abs(nextInt() - 1).toInt + 1) - } - - @tailrec final def gcd(a: Long, b: Long): Long = if (a % b == 0) b else gcd(b, a % b) - final def min(a: Long, b: Long): Long = if (a < b) a else b - final def or(a: Long, b: Long): Long = a | b - - // TODO: what about the lengths and array indices below? - - @Benchmark - def doWhileOr: Long = { - var t: Long = 0L - var i: Int = 0 - val len = size - 1 - while (i < len) { t = t ^ or(arr(i), arr(i + 1)); i += 1 } - - i = 0 - val len2 = size / 2 - while (i < len2) { t = t ^ or(arr(i + 3), arr(i + 2)); i += 1 } - - i = 0 - val len3 = size / 3 - while (i < len3) { t = t ^ or(arr(i + 1), arr(i + 2)); i += 1 } - t - } - - @Benchmark - def doWhileMin: Long = { - var t: Long = 0L - var i: Int = 0 - val len = size - 1 - while (i < len) { t = t ^ min(arr(i), arr(i + 1)); i += 1 } - - i = 0 - val len2 = size / 2 - while (i < len2) { t = t ^ min(arr(i + 3), arr(i + 2)); i += 1 } - - i = 0 - val len3 = size / 3 - while (i < len3) { t = t ^ min(arr(i + 1), arr(i + 2)); i += 1 } - - t - } - - @Benchmark - def doWhileGcd: Long = { - var t: Long = 0L - var i: Int = 0 - val len = size - 1 - while (i < len) { t = t ^ gcd(arr(i), arr(i + 1)); i += 1 } - - i = 0 - val len2 = size / 2 - while (i < len2) { t = t ^ gcd(arr(i + 3), arr(i + 2)); i += 1 } - - i = 0 - val len3 = size / 3 - while (i < len3) { t = t ^ gcd(arr(i + 1), arr(i + 2)); i += 1 } - - t - } - - @Benchmark - def doWhileIntArrayMultiply: Array[Long] = { - val arr2 = arr.clone - val len = size - 1 - var i = 0 - while (i < len) { - val value = arr2(i) - arr2(i) = value * 2 - i = i + 1 - } - arr2 - } - - @Benchmark - def doTailrecOr: Long = { - var t: Long = 0L - val len = size - 1 - @tailrec def loop1(i: Int): Unit = { - if (i < len) { t = t ^ or(arr(i), arr(i + 1)); loop1(i + 1) } - } - loop1(0) - - val len2 = size / 2 - @tailrec def loop2(i: Int): Unit = { - if (i < len2) { t = t ^ or(arr(i + 3), arr(i + 2)); loop2(i + 1) } - } - loop2(0) - - val len3 = size / 3 - @tailrec def loop3(i: Int): Unit = { - if (i < len3) { t = t ^ or(arr(i + 1), arr(i + 2)); loop3(i + 1) } - } - loop3(0) - - t - } - - @Benchmark - def doTailrecMin: Long = { - var t: Long = 0L - val len = size - 1 - @tailrec def loop1(i: Int): Unit = { - if (i < len) { t = t ^ min(arr(i), arr(i + 1)); loop1(i + 1) } - } - loop1(0) - - val len2 = size / 2 - @tailrec def loop2(i: Int): Unit = { - if (i < len2) { t = t ^ min(arr(i + 3), arr(i + 2)); loop2(i + 1) } - } - loop2(0) - - @tailrec def loop3(i: Int): Unit = { - if (i < len2) { t = t ^ min(arr(i + 1), arr(i + 2)); loop3(i + 1) } - } - loop3(0) - - t - } - - @Benchmark - def doTailrecGcd: Long = { - var t: Long = 0L - val len = size - 1 - @tailrec def loop1(i: Int): Unit = { - if (i < len) { t = t ^ gcd(arr(i), arr(i + 1)); loop1(i + 1) } - } - loop1(0) - - val len2 = size / 2 - @tailrec def loop2(i: Int): Unit = { - if (i < len2) { t = t ^ gcd(arr(i + 3), arr(i + 2)); loop2(i + 1) } - } - loop2(0) - - @tailrec def loop3(i: Int): Unit = { - if (i < len2) { t = t ^ gcd(arr(i + 1), arr(i + 2)); loop3(i + 1) } - } - loop3(0) - - t - } - - @Benchmark - def doTailrecIntArrayMultiply: Array[Long] = { - val arr2 = arr.clone - val len = size - @tailrec def loop(i: Int): Unit = { - if (i < len) { - val value = arr2(i) - arr2(i) = value * 2 - loop(i + 1) - } - } - loop(0) - - arr2 - } - - @Benchmark - def doForeachOr: Long = { - var t: Long = 0L - val len = size - 1 - (0 until len).foreach { i => t = t ^ or(arr(i), arr(i + 1)) } - - val len2 = size / 2 - (0 until len2).foreach { i => t = t ^ or(arr(i + 3), arr(i + 2)) } - - val len3 = size / 3 - (0 until len3).foreach { i => t = t ^ or(arr(i + 1), arr(i + 2)) } - - t - } - - @Benchmark - def doForeachMin: Long = { - var t: Long = 0L - val len = size - 1 - (0 until len).foreach { i => t = t ^ min(arr(i), arr(i + 1)) } - - val len2 = size / 2 - (0 until len2).foreach { i => t = t ^ min(arr(i + 3), arr(i + 2)) } - - val len3 = size / 3 - (0 until len3).foreach { i => t = t ^ min(arr(i + 1), arr(i + 2)) } - - t - } - - @Benchmark - def doForeachGcd: Long = { - var t: Long = 0L - val len = size - 1 - (0 until len).foreach { i => t = t ^ gcd(arr(i), arr(i + 1)) } - - val len2 = size / 2 - (0 until len2).foreach { i => t = t ^ gcd(arr(i + 3), arr(i + 2)) } - - val len3 = size / 3 - (0 until len3).foreach { i => t = t ^ gcd(arr(i + 1), arr(i + 2)) } - - t - } - - @Benchmark - def doForeachIntArrayMultiply: Array[Long] = { - val arr2 = arr.clone - val len = size - (0 until len).foreach { i => - val value = arr2(i) - arr2(i) = value * 2 - } - arr2 - } - - @Benchmark - def doForOr: Long = { - var t: Long = 0L - val len = size - 1 - for (i <- 0 until len) { t = t ^ or(arr(i), arr(i + 1)) } - - val len2 = size / 2 - for (i <- 0 until len2) { t = t ^ or(arr(i + 3), arr(i + 2)) } - - val len3 = size / 3 - for (i <- 0 until len3) { t = t ^ or(arr(i + 1), arr(i + 2)) } - - t - } - - @Benchmark - def doForMin: Long = { - var t: Long = 0L - val len = size - 1 - for (i <- 0 until len) { t = t ^ min(arr(i), arr(i + 1)) } - - val len2 = size / 2 - for (i <- 0 until len2) { t = t ^ min(arr(i + 3), arr(i + 2)) } - - val len3 = size / 3 - for (i <- 0 until len3) { t = t ^ min(arr(i + 1), arr(i + 2)) } - - t - } - - @Benchmark - def doForGcd: Long = { - var t: Long = 0L - val len = size - 1 - for (i <- 0 until len) { t = t ^ gcd(arr(i), arr(i + 1)) } - - val len2 = size / 2 - for (i <- 0 until len2) { t = t ^ gcd(arr(i + 3), arr(i + 2)) } - - val len3 = size / 3 - for (i <- 0 until len3) { t = t ^ gcd(arr(i + 1), arr(i + 2)) } - - t - } - - @Benchmark - def doForIntArrayMultiply: Array[Long] = { - val arr2 = arr.clone - val len = size - for (i <- 0 until len) { - val value = arr2(i) - arr2(i) = value * 2 - } - arr2 - } - - @Benchmark - def doFastForOr: Long = { - var t: Long = 0L - val len = size - 1 - fastFor(0)(_ < len, _ + 1) { i => t = t ^ or(arr(i), arr(i + 1)) } - - val len2 = size / 2 - fastFor(0)(_ < len2, _ + 1) { i => t = t ^ or(arr(i + 3), arr(i + 2)) } - - val len3 = size / 3 - fastFor(0)(_ < len3, _ + 1) { i => t = t ^ or(arr(i + 1), arr(i + 2)) } - - t - } - - @Benchmark - def doFastForMin: Long = { - var t: Long = 0L - val len = size - 1 - fastFor(0)(_ < len, _ + 1) { i => t = t ^ min(arr(i), arr(i + 1)) } - - val len2 = size / 2 - fastFor(0)(_ < len2, _ + 1) { i => t = t ^ min(arr(i + 3), arr(i + 2)) } - - val len3 = size / 3 - fastFor(0)(_ < len3, _ + 1) { i => t = t ^ min(arr(i + 1), arr(i + 2)) } - - t - } - - @Benchmark - def doFastForGcd: Long = { - var t: Long = 0L - val len = size - 1 - fastFor(0)(_ < len, _ + 1) { i => t = t ^ gcd(arr(i), arr(i + 1)) } - - val len2 = size / 2 - fastFor(0)(_ < len2, _ + 1) { i => t = t ^ gcd(arr(i + 3), arr(i + 2)) } - - val len3 = size / 3 - fastFor(0)(_ < len3, _ + 1) { i => t = t ^ gcd(arr(i + 1), arr(i + 2)) } - - t - } - - @Benchmark - def doFastForIntArrayMultiply: Array[Long] = { - val arr2 = arr.clone - val len = size - fastFor(0)(_ < len, _ + 1) { i => - { - val value = arr2(i) - arr2(i) = value * 2 - } - } - arr2 - } - -} diff --git a/core/src/main/scala-2/spire/syntax/Syntax.scala b/core/src/main/scala-2/spire/syntax/Syntax.scala index 210b107da..f429256c7 100644 --- a/core/src/main/scala-2/spire/syntax/Syntax.scala +++ b/core/src/main/scala-2/spire/syntax/Syntax.scala @@ -277,63 +277,15 @@ trait ConvertableFromSyntax { implicit def convertableOps[A: ConvertableFrom](a: A): ConvertableFromOps[A] = new ConvertableFromOps(a) } -@deprecated("Replaced by fastFor, *please* read fastFor scaladocs for details", "0.18.0") trait CforSyntax { - @deprecated("Replaced by fastFor, *please* read fastFor scaladocs for details", "0.18.0") def cfor[A](init: A)(test: A => Boolean, next: A => A)(body: A => Unit): Unit = macro Syntax.cforMacro[A] - @deprecated("Replaced by fastForRange, *please* read fastForRange scaladocs for details", "0.18.0") def cforRange(r: Range)(body: Int => Unit): Unit = macro Syntax.cforRangeMacro - @deprecated("Replaced by fastForRange2, *please* read fastForRange2 scaladocs for details", "0.18.0") def cforRange2(r1: Range, r2: Range)(body: (Int, Int) => Unit): Unit = macro Syntax.cforRange2Macro } -trait FastForSyntax { - - /** - * The `fastFor` macro will replace the `cfor` macro in Scala 3. Note that `fastFor` has simpler semantics than `cfor` - * and in general is _not_ equivalent to inlining a while-loop, particularly with respect to closures. This change is - * unlikely to affect typical use-cases, however. - * - * The implementation of `fastFor` provided for Scala 2 is _not_ a macro but is a "reference" implementation with - * semantics matching the Scala 3 macro. If you are on Scala 2 and concerned about performance you should continue - * using `cfor`. - */ - @inline final def fastFor[A](init: A)(test: A => Boolean, next: A => A)(body: A => Unit): Unit = { - var a = init - while (test(a)) { - body(a) - a = next(a) - } - } - - /** - * The `fastForRange` macro will replace the `cforRange` macro in Scala 3. Note that `fastForRange` has simpler - * semantics than `cforRange` and in general is _not_ equivalent to inlining a while-loop, particularly with respect - * to closures. This change is unlikely to affect typical use-cases, however. - * - * The implementation of `fastForRange` provided for Scala 2 is _not_ a macro but is a "reference" implementation with - * semantics matching the Scala 3 macro. If you are on Scala 2 and concerned about performance you should continue - * using `cforRange`. - */ - @inline final def fastForRange(r: Range)(body: Int => Unit): Unit = - r.foreach(body) - - /** - * The `fastForRange2` macro will replace the `cforRange2` macro in Scala 3. Note that `fastForRange2` has simpler - * semantics than `cforRange2` and in general is _not_ equivalent to inlining a while-loop, particularly with respect - * to closures. This change is unlikely to affect typical use-cases, however. - * - * The implementation of `fastForRange2` provided for Scala 2 is _not_ a macro but is a "reference" implementation - * with semantics matching the Scala 3 macro. If you are on Scala 2 and concerned about performance you should - * continue using `cforRange2`. - */ - @inline final def fastForRange2(r1: Range, r2: Range)(body: (Int, Int) => Unit): Unit = - r1.foreach(i => r2.foreach(j => body(i, j))) -} - trait LiteralsSyntax { implicit def literals(s: StringContext): Literals = new Literals(s) @@ -346,7 +298,6 @@ trait LiteralsSyntax { trait AllSyntax extends LiteralsSyntax with CforSyntax - with FastForSyntax with EqSyntax with PartialOrderSyntax with OrderSyntax diff --git a/core/src/main/scala-3/spire/syntax/CforSyntax.scala b/core/src/main/scala-3/spire/syntax/CforSyntax.scala index d52939fdb..74bb22674 100644 --- a/core/src/main/scala-3/spire/syntax/CforSyntax.scala +++ b/core/src/main/scala-3/spire/syntax/CforSyntax.scala @@ -13,21 +13,27 @@ * \*********************************************************************** */ -package spire.syntax +package spire +package syntax -// For internal use only, to help with cross-compilation -@deprecated -private[spire] trait CforSyntax: - @deprecated - private[spire] inline def cfor[A](inline init: A)(inline test: A => Boolean, inline next: A => A)( - inline body: A => Unit - ): Unit = - fastFor.fastFor(init)(test, next)(body) +trait CforSyntax: + import macros._ + import collection.immutable.NumericRange + + final type RangeLike = Range | NumericRange[Long] + + final type RangeElem[X <: RangeLike] = X match + case Range => Int + case NumericRange[Long] => Long - @deprecated - private[spire] inline def cforRange(inline r: Range)(inline body: Int => Unit): Unit = - fastFor.fastForRange(r)(body) + inline def cfor[A](inline init: A)(inline test: A => Boolean, inline next: A => A)(inline body: A => Unit): Unit = + ${ cforImpl('init, 'test, 'next, 'body) } - @deprecated - private[spire] inline def cforRange2(inline r1: Range, inline r2: Range)(inline body: (Int, Int) => Unit): Unit = - fastFor.fastForRange2(r1, r2)(body) + inline def cforRange[R <: RangeLike](inline r: R)(inline body: RangeElem[R] => Unit): Unit = + ${ cforRangeMacroGen('r, 'body) } + + inline def cforRange2[R <: RangeLike](inline r1: R, inline r2: R)( + inline body: (RangeElem[R], RangeElem[R]) => Unit + ): Unit = + cforRange(r1) { x => cforRange(r2) { y => body(x, y) } } +end CforSyntax diff --git a/core/src/main/scala-3/spire/syntax/FastForSyntax.scala b/core/src/main/scala-3/spire/syntax/FastForSyntax.scala deleted file mode 100644 index d61ee2eeb..000000000 --- a/core/src/main/scala-3/spire/syntax/FastForSyntax.scala +++ /dev/null @@ -1,39 +0,0 @@ -/* - * **********************************************************************\ - * * Project ** - * * ______ ______ __ ______ ____ ** - * * / ____/ / __ / / / / __ / / __/ (c) 2011-2021 ** - * * / /__ / /_/ / / / / /_/ / / /_ ** - * * /___ / / ____/ / / / __ / / __/ Erik Osheim, Tom Switzer ** - * * ____/ / / / / / / / | | / /__ ** - * * /_____/ /_/ /_/ /_/ |_| /____/ All rights reserved. ** - * * ** - * * Redistribution and use permitted under the MIT license. ** - * * ** - * \*********************************************************************** - */ - -package spire -package syntax - -trait FastForSyntax: - import macros._ - import collection.immutable.NumericRange - - final type RangeLike = Range | NumericRange[Long] - - final type RangeElem[X <: RangeLike] = X match - case Range => Int - case NumericRange[Long] => Long - - inline def fastFor[A](inline init: A)(inline test: A => Boolean, inline next: A => A)(inline body: A => Unit): Unit = - ${ fastForImpl('init, 'test, 'next, 'body) } - - inline def fastForRange[R <: RangeLike](inline r: R)(inline body: RangeElem[R] => Unit): Unit = - ${ fastForRangeMacroGen('r, 'body) } - - inline def fastForRange2[R <: RangeLike](inline r1: R, inline r2: R)( - inline body: (RangeElem[R], RangeElem[R]) => Unit - ): Unit = - fastForRange(r1) { x => fastForRange(r2) { y => body(x, y) } } -end FastForSyntax diff --git a/core/src/main/scala-3/spire/syntax/Syntax.scala b/core/src/main/scala-3/spire/syntax/Syntax.scala index a18dcac4f..3b1ad86c6 100644 --- a/core/src/main/scala-3/spire/syntax/Syntax.scala +++ b/core/src/main/scala-3/spire/syntax/Syntax.scala @@ -334,7 +334,6 @@ trait LiteralsSyntax { trait AllSyntax extends LiteralsSyntax with CforSyntax - with FastForSyntax with EqSyntax with PartialOrderSyntax with OrderSyntax diff --git a/core/src/main/scala-3/spire/syntax/macros/cforMacros.scala b/core/src/main/scala-3/spire/syntax/macros/cforMacros.scala index c40cc6946..e395839f8 100644 --- a/core/src/main/scala-3/spire/syntax/macros/cforMacros.scala +++ b/core/src/main/scala-3/spire/syntax/macros/cforMacros.scala @@ -19,9 +19,9 @@ import scala.quoted.* import scala.collection.immutable.NumericRange import scala.PartialFunction.cond -import spire.syntax.fastFor.{RangeElem, RangeLike} +import spire.syntax.cfor.{RangeElem, RangeLike} -def fastForImpl[R: Type](init: Expr[R], test: Expr[R => Boolean], next: Expr[R => R], body: Expr[R => Unit])(using +def cforImpl[R: Type](init: Expr[R], test: Expr[R => Boolean], next: Expr[R => R], body: Expr[R => Unit])(using Quotes ): Expr[Unit] = import quotes.reflect.* @@ -34,9 +34,9 @@ def fastForImpl[R: Type](init: Expr[R], test: Expr[R => Boolean], next: Expr[R = } letFunc("test", test)(t => letFunc("next", next)(n => letFunc("body", body)(b => code(t, n, b)))) -end fastForImpl +end cforImpl -def fastForRangeMacroGen[R <: RangeLike: Type](r: Expr[R], body: Expr[RangeElem[R] => Unit])(using +def cforRangeMacroGen[R <: RangeLike: Type](r: Expr[R], body: Expr[RangeElem[R] => Unit])(using quotes: Quotes ): Expr[Unit] = import quotes.reflect.* @@ -46,7 +46,7 @@ def fastForRangeMacroGen[R <: RangeLike: Type](r: Expr[R], body: Expr[RangeElem[ case '{ $r: NumericRange[Long] } => RangeForImpl.ofLong(r, body.asExprOf[Long => Unit]) case '{ $r } => report.error(s"Ineligible Range type ", r); '{} -end fastForRangeMacroGen +end cforRangeMacroGen private object RangeForImpl: type Code[T] = Expr[T => Unit] => Expr[Unit] diff --git a/core/src/main/scala/spire/syntax/package.scala b/core/src/main/scala/spire/syntax/package.scala index 5c351adeb..f9aa63fc0 100644 --- a/core/src/main/scala/spire/syntax/package.scala +++ b/core/src/main/scala/spire/syntax/package.scala @@ -16,9 +16,7 @@ package spire package object syntax { - @deprecated("Replaced by fastFor, *please* read fastFor scaladocs for details", "0.18.0") object cfor extends CforSyntax - object fastFor extends FastForSyntax object literals extends LiteralsSyntax object eq extends EqSyntax diff --git a/docs/src/main/mdoc/index.md b/docs/src/main/mdoc/index.md index a82372474..6abe250fb 100644 --- a/docs/src/main/mdoc/index.md +++ b/docs/src/main/mdoc/index.md @@ -431,7 +431,7 @@ object SIDemo { } ``` -Spire also provides a loop macro called `fastFor` (previously known as `cfor`) whose syntax bears a slight +Spire also provides a loop macro called `cfor` (previously known as `cfor`) whose syntax bears a slight resemblance to a traditional for-loop from C or Java. This macro expands to a tail-recursive function, which will inline literal function arguments. @@ -439,20 +439,20 @@ The macro can be nested in itself and compares favorably with other looping constructs in Scala such as `for` and `while`: ```scala mdoc:silent:nest -import spire.syntax.fastFor._ +import spire.syntax.cfor._ // print numbers 1 through 10 -fastFor(0)(_ < 10, _ + 1) { i => +cfor(0)(_ < 10, _ + 1) { i => println(i) } // naive sorting algorithm def selectionSort(ns: Array[Int]) = { val limit = ns.length -1 - fastFor(0)(_ < limit, _ + 1) { i => + cfor(0)(_ < limit, _ + 1) { i => var k = i val n = ns(i) - fastFor(i + 1)(_ <= limit, _ + 1) { j => + cfor(i + 1)(_ <= limit, _ + 1) { j => if (ns(j) < ns(k)) k = j } ns(i) = ns(k) diff --git a/examples/src/main/scala/spire/example/kleene.scala b/examples/src/main/scala/spire/example/kleene.scala index b3aaa0435..9b0b277c9 100644 --- a/examples/src/main/scala/spire/example/kleene.scala +++ b/examples/src/main/scala/spire/example/kleene.scala @@ -156,8 +156,8 @@ object KleeneDemo { def apply[A: ClassTag](f: (Int, Int) => A)(implicit dim: Dim): Matrix[A] = { val n = dim.n val arr = new Array[A](n * n) - fastFor(0)(_ < n, _ + 1) { y => - fastFor(0)(_ < n, _ + 1) { x => + cfor(0)(_ < n, _ + 1) { y => + cfor(0)(_ < n, _ + 1) { x => arr(y * n + x) = f(x, y) } } @@ -200,7 +200,7 @@ object KleeneDemo { def *(rhs: Matrix[A])(implicit rig: Rig[A]): Matrix[A] = Matrix { (x, y) => var total = rig.zero - fastFor(0)(_ < dim.n, _ + 1)(j => total += lhs(j, y) * rhs(x, j)) + cfor(0)(_ < dim.n, _ + 1)(j => total += lhs(j, y) * rhs(x, j)) total } } @@ -211,10 +211,10 @@ object KleeneDemo { val s = Show[A] val n = m.dim.n val lines = Array.fill(n)("") - fastFor(0)(_ < n, _ + 1) { x => - fastFor(0)(_ < n, _ + 1)(y => lines(y) += s.show(m(x, y)) + " ") + cfor(0)(_ < n, _ + 1) { x => + cfor(0)(_ < n, _ + 1)(y => lines(y) += s.show(m(x, y)) + " ") val len = lines.foldLeft(0)(_ max _.length) - fastFor(0)(_ < n, _ + 1)(y => lines(y) += " " * (len - lines(y).length)) + cfor(0)(_ < n, _ + 1)(y => lines(y) += " " * (len - lines(y).length)) } lines.mkString("\n") + "\n" } diff --git a/examples/src/main/scala/spire/example/kmeans.scala b/examples/src/main/scala/spire/example/kmeans.scala index ad8376151..d518fc3d6 100644 --- a/examples/src/main/scala/spire/example/kmeans.scala +++ b/examples/src/main/scala/spire/example/kmeans.scala @@ -43,10 +43,10 @@ object KMeansExample extends App { def assign(clusters: Array[V]): Array[Int] = { val assignments = new Array[Int](points.length) - fastFor(0)(_ < points.length, _ + 1) { i => + cfor(0)(_ < points.length, _ + 1) { i => var min = (points(i) - clusters(0)).norm var idx = 0 - fastFor(1)(_ < clusters.length, _ + 1) { j => + cfor(1)(_ < clusters.length, _ + 1) { j => val dist = (points(i) - clusters(j)).norm if (dist < min) { min = dist @@ -73,12 +73,12 @@ object KMeansExample extends App { } else { val clusters = Array.fill[V](clusters0.length)(vs.zero) val counts = new Array[Int](clusters0.length) - fastFor(0)(_ < points.length, _ + 1) { i => + cfor(0)(_ < points.length, _ + 1) { i => val idx = assignments(i) clusters(idx) = clusters(idx) + points(i) counts(idx) += 1 } - fastFor(0)(_ < clusters.length, _ + 1) { j => + cfor(0)(_ < clusters.length, _ + 1) { j => clusters(j) = clusters(j) :/ vs.scalar.fromInt(counts(j)) } loop(assignments, clusters) @@ -95,7 +95,7 @@ object KMeansExample extends App { // wants before we return the clusters. val bldr = cbf.newBuilder - fastFor(0)(_ < clusters.length, _ + 1) { i => + cfor(0)(_ < clusters.length, _ + 1) { i => bldr += clusters(i) } bldr.result() @@ -115,7 +115,7 @@ object KMeansExample extends App { }.toVector val bldr = cbf.newBuilder - fastFor(0)(_ < n, _ + 1) { _ => + cfor(0)(_ < n, _ + 1) { _ => bldr += centers(nextInt(k)) + randPoint(nextGaussian()) } bldr.result() diff --git a/examples/src/main/scala/spire/example/loops.scala b/examples/src/main/scala/spire/example/loops.scala index 757a3b7cf..d20f46f3c 100644 --- a/examples/src/main/scala/spire/example/loops.scala +++ b/examples/src/main/scala/spire/example/loops.scala @@ -20,15 +20,15 @@ import spire.implicits._ class Loops { def nested(): Unit = { - fastFor(0)(_ < 5, _ + 1) { y => - fastFor(0)(_ < 3, _ + 1) { x => + cfor(0)(_ < 5, _ + 1) { y => + cfor(0)(_ < 3, _ + 1) { x => println((x, y)) } } } def simple(): Unit = { - fastFor(0)(_ < 10, _ + 1) { i => println(i) } + cfor(0)(_ < 10, _ + 1) { i => println(i) } } def simplew(): Unit = { diff --git a/examples/src/main/scala/spire/example/mandelbrot.scala b/examples/src/main/scala/spire/example/mandelbrot.scala index 23ffe99dd..f52aef142 100644 --- a/examples/src/main/scala/spire/example/mandelbrot.scala +++ b/examples/src/main/scala/spire/example/mandelbrot.scala @@ -50,8 +50,8 @@ object MandelbrotDemo { def display(s: String, n: Int) = print(Xterm.rainbow(n) + s) // render the area in ASCII, using o's and spaces. - fastFor(0)(_ <= rows, _ + 1) { y => - fastFor(0)(_ <= cols, _ + 1) { x => + cfor(0)(_ <= rows, _ + 1) { y => + cfor(0)(_ <= cols, _ + 1) { x => // if n indices(i) = i } - fastFor(V.dimensions - 1)(_ >= indices.length, _ - 1) { i => + cfor(0)(_ < indices.length, _ + 1) { i => indices(i) = i } + cfor(V.dimensions - 1)(_ >= indices.length, _ - 1) { i => val j = nextInt(i + 1) if (j < indices.length) indices(j) = i @@ -147,7 +147,7 @@ trait RandomForest[V, @sp(Double) F, @sp(Double) K] { def sample(): Array[Int] = { val sample = new Array[Int](opts.numPointsSample) - fastFor(0)(_ < sample.length, _ + 1) { i => + cfor(0)(_ < sample.length, _ + 1) { i => sample(i) = nextInt(data.length) } sample @@ -158,7 +158,7 @@ trait RandomForest[V, @sp(Double) F, @sp(Double) K] { def region(members: Array[Int]): Region = { var d = Region.empty - fastFor(0)(_ < members.length, _ + 1) { i => + cfor(0)(_ < members.length, _ + 1) { i => d += outputs(members(i)) } d @@ -178,7 +178,7 @@ trait RandomForest[V, @sp(Double) F, @sp(Double) K] { var minVar = -1 var minIdx = -1 - fastFor(0)(_ < vars.length, _ + 1) { i => + cfor(0)(_ < vars.length, _ + 1) { i => val axis = vars(i) var leftRegion = Region.empty var rightRegion = region0 @@ -190,7 +190,7 @@ trait RandomForest[V, @sp(Double) F, @sp(Double) K] { members.qsortBy(data(_).coord(axis)) - fastFor(0)(_ < (members.length - 1), _ + 1) { j => + cfor(0)(_ < (members.length - 1), _ + 1) { j => // We move point j from the right region to the left and see if our // error is reduced. diff --git a/tests/shared/src/test/scala-3/scala/spire/syntax/FastForSuite.scala b/tests/shared/src/test/scala-3/scala/spire/syntax/FastForSuite.scala deleted file mode 100644 index 64e9e8c91..000000000 --- a/tests/shared/src/test/scala-3/scala/spire/syntax/FastForSuite.scala +++ /dev/null @@ -1,176 +0,0 @@ -/* - * **********************************************************************\ - * * Project ** - * * ______ ______ __ ______ ____ ** - * * / ____/ / __ / / / / __ / / __/ (c) 2011-2021 ** - * * / /__ / /_/ / / / / /_/ / / /_ ** - * * /___ / / ____/ / / / __ / / __/ Erik Osheim, Tom Switzer ** - * * ____/ / / / / / / / | | / /__ ** - * * /_____/ /_/ /_/ /_/ |_| /____/ All rights reserved. ** - * * ** - * * Redistribution and use permitted under the MIT license. ** - * * ** - * \*********************************************************************** - */ - -package spire -package syntax - -import scala.collection.mutable - -class FastForSuite extends munit.FunSuite { - - import spire.syntax.fastFor._ - - test("simple fastFor") { - val l = mutable.ListBuffer[Int]() - fastFor(0)(_ < 5, _ + 1) { x => - l.append(x) - } - assertEquals(l.toList, List(0, 1, 2, 3, 4)) - } - - test("nested fastFor") { - val s = mutable.Set.empty[Int] - fastFor(0)(_ < 10, _ + 1) { x => - fastFor(10)(_ < 100, _ + 10) { y => - s.add(x + y) - } - } - assertEquals(s.toSet, (10 to 99).toSet) - } - - test("symbol collision fastFor") { - val b = mutable.ArrayBuffer.empty[Int] - fastFor(0)(_ < 3, _ + 1) { x => - fastFor(0)(_ < 2, _ + 1) { y => - val x = y - b += x - } - } - assertEquals(b.toList, List(0, 1, 0, 1, 0, 1)) - } - - test("functions with side effects in fastFor") { - val b = mutable.ArrayBuffer.empty[Int] - var v = 0 - fastFor(0)({ v += 1; _ < 3 }, { v += 10; _ + 1 }) { - v += 100 - x => { - b += x - } - } - assertEquals(v, 111) - assertEquals(b.toList, List(0, 1, 2)) - } - - test("functions with side effects function values in fastFor") { - val b = mutable.ArrayBuffer.empty[Int] - var v = 0 - def test: Int => Boolean = { v += 1; _ < 3 } - def incr: Int => Int = { v += 10; _ + 1 } - def body: Int => Unit = { - v += 100 - x => { - b += x - } - } - fastFor(0)(test, incr)(body) - assertEquals(v, 111) - assertEquals(b.toList, List(0, 1, 2)) - } - - test("functions with side effects function by-value params in fastFor") { - val b = mutable.ArrayBuffer.empty[Int] - var v = 0 - def run(test: => (Int => Boolean), incr: => (Int => Int), body: => (Int => Unit)): Unit = { - fastFor(0)(test, incr)(body) - } - run( - { v += 1; _ < 3 }, - { v += 10; _ + 1 }, { - v += 100 - x => { - b += x - } - } - ) - assertEquals(v, 111) - assertEquals(b.toList, List(0, 1, 2)) - } - - test("capture value in closure") { // same behavior as cfor - val b1 = collection.mutable.ArrayBuffer.empty[() => Int] - fastFor(0)(_ < 3, _ + 1) { x => - b1 += (() => x) - } - val b2 = collection.mutable.ArrayBuffer[() => Int]() - var i = 0 - while (i < 3) { - b2 += (() => i) - i += 1 - } - assertEquals(b1.map(_.apply()).toList, b2.map(_.apply()).toList) - } - - test("capture value in inner class") { - val b = collection.mutable.ArrayBuffer[Int]() - fastFor(0)(_ < 3, _ + 1) { x => - { - class A { def f = x } - b += (new A().f) - } - } - assertEquals(b.toList, List(0, 1, 2)) - } - - test("type tree bug fixed") { - val arr = Array((1, 2), (2, 3), (4, 5)) - var t = 0 - fastFor(0)(_ < arr.length, _ + 1) { i => - val (a, b) = arr(i) - t += a + 2 * b - } - assertEquals(t, 27) - } - - test("destructure tuples") { - var t = 0 - fastFor((0, 0))(_._1 < 3, t => (t._1 + 1, t._2 + 2)) { case (a, b) => - t += 3 * a + b - } - assertEquals(t, 15) - } - - test("fastForRange(1 until 4)") { - var t = 0 - fastForRange(1 until 4) { x => - t += x - } - assertEquals(t, 6) - } - - test("fastForRange(0 to 10 by 2)") { - var t = 0 - fastForRange(0 to 10 by 2) { x => - t += x - } - assertEquals(t, 30) - } - - test("fastForRange(3 to 1 by -1)") { - var t = 0 - fastForRange(3 to 1 by -1) { x => - t += x - } - assertEquals(t, 6) - } - - test("fastForRange(0 to 0 by -1)") { - var t = 0 - fastForRange(0 to 0 by -1) { x => - t += 1 - } - assertEquals(t, 1) - } -} diff --git a/tests/shared/src/test/scala-2/scala/spire/syntax/CforSuite.scala b/tests/shared/src/test/scala/spire/syntax/CforSuite.scala similarity index 100% rename from tests/shared/src/test/scala-2/scala/spire/syntax/CforSuite.scala rename to tests/shared/src/test/scala/spire/syntax/CforSuite.scala From 90495726148e0a3a9d1917067269c2cdf193b473 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Fri, 7 Jan 2022 01:49:47 +0000 Subject: [PATCH 2/2] Remove some lingering references --- .../scala/spire/benchmark/CForBenchmark.scala | 59 ------------------- 1 file changed, 59 deletions(-) diff --git a/benchmark/src/main/scala/spire/benchmark/CForBenchmark.scala b/benchmark/src/main/scala/spire/benchmark/CForBenchmark.scala index ab89e7e0f..9bffbafab 100644 --- a/benchmark/src/main/scala/spire/benchmark/CForBenchmark.scala +++ b/benchmark/src/main/scala/spire/benchmark/CForBenchmark.scala @@ -24,7 +24,6 @@ import scala.util.Random import Random._ import spire.syntax.cfor._ -import spire.syntax.fastFor._ import Arrays.init @@ -372,62 +371,4 @@ class CForBenchmarks { arr2 } - @Benchmark - def doFastForOr: Long = { - var t: Long = 0L - val len = size - 1 - fastFor(0)(_ < len, _ + 1) { i => t = t ^ or(arr(i), arr(i + 1)) } - - val len2 = size / 2 - fastFor(0)(_ < len2, _ + 1) { i => t = t ^ or(arr(i + 3), arr(i + 2)) } - - val len3 = size / 3 - fastFor(0)(_ < len3, _ + 1) { i => t = t ^ or(arr(i + 1), arr(i + 2)) } - - t - } - - @Benchmark - def doFastForMin: Long = { - var t: Long = 0L - val len = size - 1 - fastFor(0)(_ < len, _ + 1) { i => t = t ^ min(arr(i), arr(i + 1)) } - - val len2 = size / 2 - fastFor(0)(_ < len2, _ + 1) { i => t = t ^ min(arr(i + 3), arr(i + 2)) } - - val len3 = size / 3 - fastFor(0)(_ < len3, _ + 1) { i => t = t ^ min(arr(i + 1), arr(i + 2)) } - - t - } - - @Benchmark - def doFastForGcd: Long = { - var t: Long = 0L - val len = size - 1 - fastFor(0)(_ < len, _ + 1) { i => t = t ^ gcd(arr(i), arr(i + 1)) } - - val len2 = size / 2 - fastFor(0)(_ < len2, _ + 1) { i => t = t ^ gcd(arr(i + 3), arr(i + 2)) } - - val len3 = size / 3 - fastFor(0)(_ < len3, _ + 1) { i => t = t ^ gcd(arr(i + 1), arr(i + 2)) } - - t - } - - @Benchmark - def doFastForIntArrayMultiply: Array[Long] = { - val arr2 = arr.clone - val len = size - fastFor(0)(_ < len, _ + 1) { i => - { - val value = arr2(i) - arr2(i) = value * 2 - } - } - arr2 - } - }