Skip to content
Permalink
Browse files

Terrible initial derives implementation

  • Loading branch information
travisbrown committed Jan 25, 2020
1 parent 2b288bf commit ce5f17cd751ffa15e4f9b53a133130dabb33a526
Showing with 845 additions and 12 deletions.
  1. +3 −0 .scalafmt.conf
  2. +1 −1 .travis.yml
  3. +47 −7 build.sbt
  4. +52 −0 modules/benchmark-dotty/src/main/scala/io/circe/benchmark/DerivesBenchmark.scala
  5. +298 −0 modules/core/shared/src/main/scala-0/io/circe/Derivation.scala
  6. +5 −0 modules/core/shared/src/main/scala-2/io/circe/Derivation.scala
  7. +1 −1 modules/core/shared/src/main/scala/io/circe/Codec.scala
  8. +2 −1 modules/core/shared/src/main/scala/io/circe/Decoder.scala
  9. +1 −1 modules/core/shared/src/main/scala/io/circe/Encoder.scala
  10. +21 −0 modules/generic/shared/src/main/scala-0/io/circe/generic/auto.scala
  11. +29 −0 modules/generic/shared/src/main/scala-0/io/circe/generic/semiauto.scala
  12. 0 modules/generic/shared/src/main/{scala → scala-2}/io/circe/generic/AutoDerivation.scala
  13. 0 modules/generic/shared/src/main/{scala → scala-2}/io/circe/generic/Deriver.scala
  14. 0 modules/generic/shared/src/main/{scala → scala-2}/io/circe/generic/JsonCodec.scala
  15. 0 modules/generic/shared/src/main/{scala → scala-2}/io/circe/generic/auto/package.scala
  16. 0 modules/generic/shared/src/main/{scala → scala-2}/io/circe/generic/codec/DerivedAsObjectCodec.scala
  17. 0 modules/generic/shared/src/main/{scala → scala-2}/io/circe/generic/codec/ReprAsObjectCodec.scala
  18. 0 modules/generic/shared/src/main/{scala → scala-2}/io/circe/generic/decoding/DerivedDecoder.scala
  19. 0 ...neric/shared/src/main/{scala → scala-2}/io/circe/generic/decoding/IncompleteDerivedDecoders.scala
  20. 0 modules/generic/shared/src/main/{scala → scala-2}/io/circe/generic/decoding/ReprDecoder.scala
  21. 0 .../generic/shared/src/main/{scala → scala-2}/io/circe/generic/encoding/DerivedAsObjectEncoder.scala
  22. 0 ...les/generic/shared/src/main/{scala → scala-2}/io/circe/generic/encoding/ReprAsObjectEncoder.scala
  23. 0 modules/generic/shared/src/main/{scala → scala-2}/io/circe/generic/encoding/package.scala
  24. +1 −1 modules/generic/shared/src/main/{scala → scala-2}/io/circe/generic/semiauto.scala
  25. 0 modules/generic/shared/src/main/{scala → scala-2}/io/circe/generic/util/PatchWithOptions.scala
  26. 0 ...les/generic/shared/src/main/{scala → scala-2}/io/circe/generic/util/macros/DerivationMacros.scala
  27. 0 modules/generic/shared/src/main/{scala → scala-2}/io/circe/generic/util/macros/ExportMacros.scala
  28. 0 modules/generic/shared/src/main/{scala → scala-2}/io/circe/generic/util/macros/JsonCodecMacros.scala
  29. +80 −0 modules/generic/shared/src/test/scala-0/io/circe/generic/AutoDerivedSuite.scala
  30. +164 −0 modules/generic/shared/src/test/scala-0/io/circe/generic/SemiautoDerivedSuite.scala
  31. 0 modules/generic/shared/src/test/{scala → scala-2}/io/circe/generic/AutoDerivedSuite.scala
  32. 0 modules/generic/shared/src/test/{scala → scala-2}/io/circe/generic/JsonCodecMacrosSuite.scala
  33. 0 modules/generic/shared/src/test/{scala → scala-2}/io/circe/generic/SemiautoDerivedSuite.scala
  34. +140 −0 modules/tests/shared/src/test/scala-0/io/circe/DerivesSuite.scala
@@ -14,3 +14,6 @@ rewrite.rules = [
AsciiSortImports,
PreferCurlyFors
]
project.excludeFilters = [
scala-0/io/circe/Derivation.scala
]
@@ -25,7 +25,7 @@ install:
script:
- if [[ "$TRAVIS_SCALA_VERSION" == 0.* ]];
then
sbt ++$TRAVIS_SCALA_VERSION numbersJVM/test coreJVM/test testsJVM/test;
sbt ++$TRAVIS_SCALA_VERSION numbersJVM/test coreJVM/test genericJVM/test jawn/test testsJVM/test;
else
sbt ++$TRAVIS_SCALA_VERSION clean coverage validateJVM benchmark/test &&
sbt ++$TRAVIS_SCALA_VERSION benchmark/test;
@@ -128,7 +128,9 @@ def addDisciplineScalaTest(testScope: Boolean = true) = libraryDependencies += {
* We omit all Scala.js projects from Unidoc generation.
*/
def noDocProjects(sv: String): Seq[ProjectReference] =
(circeCrossModules.map(_._2) :+ tests :+ genericSimple :+ genericSimpleJS).map(p => p: ProjectReference)
(circeCrossModules.map(_._2) :+ tests :+ genericSimple :+ genericSimpleJS :+ benchmarkDotty).map(p =>
p: ProjectReference
)

lazy val docSettings = allSettings ++ Seq(
micrositeName := "circe",
@@ -302,16 +304,36 @@ lazy val coreJS = coreBase.js
lazy val genericBase = circeCrossModule("generic", mima = previousCirceVersion)
.settings(macroSettings)
.settings(
libraryDependencies += "com.chuusai" %%% "shapeless" % shapelessVersion,
Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.AllLibraryJars
libraryDependencies ++= (if (isDotty.value) Nil else Seq("com.chuusai" %%% "shapeless" % shapelessVersion)),
Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.AllLibraryJars,
Compile / unmanagedSourceDirectories ++= {
def extraDirs(suffix: String) =
CrossType.Full.sharedSrcDir(baseDirectory.value, "main").toList.map(f => file(f.getPath + suffix))

CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, y)) => extraDirs("-2") ++ (if (y >= 13) extraDirs("-2.13+") else Nil)
case Some((0, _)) => extraDirs("-0") ++ extraDirs("-2.13+")
case _ => Nil
}
},
Test / unmanagedSourceDirectories ++= {
def extraDirs(suffix: String) =
CrossType.Full.sharedSrcDir(baseDirectory.value, "test").toList.map(f => file(f.getPath + suffix))

CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, y)) => extraDirs("-2") ++ (if (y >= 13) extraDirs("-2.13+") else Nil)
case Some((0, _)) => extraDirs("-0") ++ extraDirs("-2.13+")
case _ => Nil
}
}
)
.jsSettings(
libraryDependencies ++= Seq(
"org.typelevel" %% "jawn-parser" % jawnVersion % Test,
"io.github.cquiroz" %%% "scala-java-time" % scalaJavaTimeVersion % Test
)
)
.dependsOn(coreBase, testsBase % Test, literalBase % Test)
.dependsOn(coreBase, testsBase % Test)

lazy val generic = genericBase.jvm
lazy val genericJS = genericBase.js
@@ -455,9 +477,17 @@ lazy val testsBase = circeCrossModule("tests", mima = None)
file("modules/tests") / "shared" / "src" / "main" / "resources",
Compile / unmanagedSourceDirectories ++= {
def extraDirs(suffix: String) =
List("main", "test")
.flatMap(CrossType.Full.sharedSrcDir(baseDirectory.value, _))
.map(f => file(f.getPath + suffix))
List("main").flatMap(CrossType.Full.sharedSrcDir(baseDirectory.value, _)).map(f => file(f.getPath + suffix))

CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, y)) => extraDirs("-2") ++ (if (y >= 13) extraDirs("-2.13+") else Nil)
case Some((0, _)) => extraDirs("-0") ++ extraDirs("-2.13+")
case _ => Nil
}
},
Test / unmanagedSourceDirectories ++= {
def extraDirs(suffix: String) =
List("test").flatMap(CrossType.Full.sharedSrcDir(baseDirectory.value, _)).map(f => file(f.getPath + suffix))

CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, y)) => extraDirs("-2") ++ (if (y >= 13) extraDirs("-2.13+") else Nil)
@@ -510,6 +540,16 @@ lazy val benchmark = circeModule("benchmark", mima = None)
.enablePlugins(JmhPlugin)
.dependsOn(core, generic, jawn)

lazy val benchmarkDotty = circeModule("benchmark-dotty", mima = None)
.settings(noPublishSettings)
.settings(
scalacOptions ~= {
_.filterNot(Set("-Yno-predef"))
}
)
.enablePlugins(JmhPlugin)
.dependsOn(core, jawn)

lazy val publishSettings = Seq(
releaseCrossBuild := true,
releasePublishArtifactsAction := PgpKeys.publishSigned.value,
@@ -0,0 +1,52 @@
package io.circe.benchmark

import cats.kernel.Eq
import io.circe.{ Codec, Decoder, Encoder, HCursor, Json }
import java.util.concurrent.TimeUnit
import org.openjdk.jmh.annotations._

case class Foo(s: String, d: Double, i: Int, l: Long, bs: List[Boolean]) derives Codec.AsObject

object Foo {
implicit val eqFoo: Eq[Foo] = Eq.fromUniversalEquals[Foo]
}

/**
* Compare the performance of derived and non-derived codecs.
*
* The following command will run the benchmarks with reasonable settings:
*
* > sbt "benchmarkDotty/jmh:run -i 10 -wi 10 -f 2 -t 1 io.circe.benchmark.DerivesBenchmark"
*/
@State(Scope.Thread)
@BenchmarkMode(Array(Mode.Throughput))
@OutputTimeUnit(TimeUnit.SECONDS)
class DerivesBenchmark {
private[this] val nonDerivedCodec: Codec.AsObject[Foo] =
Codec.forProduct5("s", "d", "i", "l", "bs")(Foo.apply) {
case Foo(s, d, i, l, bs) => (s, d, i, l, bs)
}

val exampleFoo: Foo = Foo(
"abcdefghijklmnopqrstuvwxyz",
1001.0,
2002,
3003L,
List(true, false, true, false, true, false, true, false, true)
)

val derivedCodec = Codec[Foo]
val exampleFooJson = derivedCodec.apply(exampleFoo)

@Benchmark
def decodeDerived: Decoder.Result[Foo] = derivedCodec.decodeJson(exampleFooJson)

@Benchmark
def decodeNonDerived: Decoder.Result[Foo] = nonDerivedCodec.decodeJson(exampleFooJson)

@Benchmark
def encodeDerived: Json = derivedCodec.apply(exampleFoo)

@Benchmark
def encodeNonDerived: Json = nonDerivedCodec(exampleFoo)
}

0 comments on commit ce5f17c

Please sign in to comment.
You can’t perform that action at this time.