Skip to content

Commit

Permalink
Adopt @ulfjack's Ryu algorithm for faster serialization of floats and…
Browse files Browse the repository at this point in the history
… doubles (part of #13 issue)
  • Loading branch information
plokhotnyuk committed Jul 28, 2018
1 parent 1e658c3 commit 1224719
Show file tree
Hide file tree
Showing 4 changed files with 488 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,24 @@ class ArrayOfDoublesBenchmarkSpec extends BenchmarkSpecBase {
benchmark.readUPickle() shouldBe benchmark.obj
}
"serialize properly" in {
toString(benchmark.writeAVSystemGenCodec()) shouldBe benchmark.jsonString
toString(benchmark.writeCirce()) shouldBe benchmark.jsonString
sameOrBetter(toString(benchmark.writeAVSystemGenCodec()), benchmark.jsonString)
sameOrBetter(toString(benchmark.writeCirce()), benchmark.jsonString)
//FIXME: dsl-json serializes doubles in a plain representation
//toString(benchmark.writeDslJsonJava()) shouldBe benchmark.jsonString
toString(benchmark.writeJacksonScala()) shouldBe benchmark.jsonString
toString(benchmark.writeJsoniterScala()) shouldBe benchmark.jsonString
toString(benchmark.preallocatedBuf, benchmark.preallocatedOff, benchmark.writeJsoniterScalaPrealloc()) shouldBe benchmark.jsonString
//sameOrBetter(toString(benchmark.writeDslJsonJava()), benchmark.jsonString)
sameOrBetter(toString(benchmark.writeJacksonScala()), benchmark.jsonString)
sameOrBetter(toString(benchmark.writeJsoniterScala()), benchmark.jsonString)
sameOrBetter(toString(benchmark.preallocatedBuf, benchmark.preallocatedOff, benchmark.writeJsoniterScalaPrealloc()), benchmark.jsonString)
//FIXME: Play serializes doubles in different format than toString: 0.0 as 0, 7.0687002407403325E18 as 7068700240740332500
//toString(benchmark.writePlayJson()) shouldBe benchmark.jsonString
toString(benchmark.writeUPickle()) shouldBe benchmark.jsonString
//sameOrBetter(toString(benchmark.writePlayJson()), benchmark.jsonString)
sameOrBetter(toString(benchmark.writeUPickle()), benchmark.jsonString)
}
}


private[this] def sameOrBetter(actual: String, expected: String): Unit =
actual.substring(1, actual.length - 1).split(',')
.zip(expected.substring(1, expected.length - 1).split(',')).foreach { case (a, e) =>
require(a.toDouble == e.toDouble && a.length <= e.length,
s"expected the same or better: $e, but got: $a")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,24 @@ class ArrayOfFloatsBenchmarkSpec extends BenchmarkSpecBase {
}
"serialize properly" in {
//FIXME: AVSystem GenCodec serializes double values instead of float
//toString(benchmark.writeAVSystemGenCodec()) shouldBe benchmark.jsonString
toString(benchmark.writeCirce()) shouldBe benchmark.jsonString
toString(benchmark.writeDslJsonJava()) shouldBe benchmark.jsonString
toString(benchmark.writeJacksonScala()) shouldBe benchmark.jsonString
toString(benchmark.writeJsoniterScala()) shouldBe benchmark.jsonString
toString(benchmark.preallocatedBuf, benchmark.preallocatedOff, benchmark.writeJsoniterScalaPrealloc()) shouldBe benchmark.jsonString
//sameOrBetter(toString(benchmark.writeAVSystemGenCodec()), benchmark.jsonString)
sameOrBetter(toString(benchmark.writeCirce()), benchmark.jsonString)
sameOrBetter(toString(benchmark.writeDslJsonJava()), benchmark.jsonString)
sameOrBetter(toString(benchmark.writeJacksonScala()), benchmark.jsonString)
sameOrBetter(toString(benchmark.writeJsoniterScala()), benchmark.jsonString)
sameOrBetter(toString(benchmark.preallocatedBuf, benchmark.preallocatedOff, benchmark.writeJsoniterScalaPrealloc()),
benchmark.jsonString)
//FIXME: Play-JSON serializes double values instead of float
//toString(benchmark.writePlayJson()) shouldBe benchmark.jsonString
//sameOrBetter(toString(benchmark.writePlayJson()), benchmark.jsonString)
//FIXME: uPickle serializes double values instead of float
//toString(benchmark.writeUPickle()) shouldBe benchmark.jsonString
//sameOrBetter(toString(benchmark.writeUPickle()), benchmark.jsonString)
}
}

private[this] def sameOrBetter(actual: String, expected: String): Unit =
actual.substring(1, actual.length - 1).split(',')
.zip(expected.substring(1, expected.length - 1).split(',')).foreach { case (a, e) =>
require(a.toFloat == e.toFloat && a.length <= e.length,
s"expected the same or better: $e, but got: $a")
}
}
Loading

0 comments on commit 1224719

Please sign in to comment.