From fbb64ca21eb94eda9f65a5cea736922a9c90e65d Mon Sep 17 00:00:00 2001 From: plokhotnyuk Date: Mon, 9 Jan 2023 12:52:59 +0100 Subject: [PATCH 1/9] Setting version to 2.20.3-SNAPSHOT --- version.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.sbt b/version.sbt index b607a349f..b325a985c 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -ThisBuild / version := "2.20.2" +ThisBuild / version := "2.20.3-SNAPSHOT" From 22838cfb9fbc6031375f7ccdcf4f534c099c9239 Mon Sep 17 00:00:00 2001 From: plokhotnyuk Date: Mon, 9 Jan 2023 15:30:09 +0100 Subject: [PATCH 2/9] Update docs --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 259706150..f779be472 100644 --- a/README.md +++ b/README.md @@ -520,7 +520,7 @@ You will get the profile in the `jsoniter-scala-benchmark/jvm/target/jfr-reports To run benchmarks with recordings by [Async profiler](https://github.com/jvm-profiling-tools/async-profiler), extract binaries to `/opt/async-profiler` directory and use command like this: ```sh -sbt jsoniter-scala-benchmarkJVM/clean 'jsoniter-scala-benchmarkJVM/jmh:run -prof "async:dir=target/async-reports;interval=1000000;output=flamegraph;libPath=/opt/async-profiler/build/libasyncProfiler.so" --p size=128 -wi 5 -i 10 jsoniterScala' +sbt jsoniter-scala-benchmarkJVM/clean 'jsoniter-scala-benchmarkJVM/jmh:run -prof "async:dir=target/async-reports;interval=1000000;output=flamegraph;libPath=/opt/async-profiler/build/libasyncProfiler.so" --p size=128 -jvmArgsAppend "-XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints" -wi 5 -i 10 jsoniterScala' ``` Now you can open direct and reverse flame graphs in the `jsoniter-scala-benchmark/jvmtarget/async-reports` directory. @@ -587,6 +587,10 @@ cd jsoniter-scala-benchmark/js open scala-3-fullopt.html ``` +Then select the batch mode with storing results in a `.zip` file. + +Use the following command for merging unpacked results from browsers: `jq -s '[.[][]]' firefox/*.json firefox.json` + The released version of Scala.js benchmarks is available [here](https://plokhotnyuk.github.io/jsoniter-scala/scala-3-fullopt.html). ### Run compilation time benchmarks From 3a03499a559dbc7e1141ba3f9d69faa3ed8e01dc Mon Sep 17 00:00:00 2001 From: plokhotnyuk Date: Mon, 9 Jan 2023 21:45:07 +0100 Subject: [PATCH 3/9] More efficient serialization of `Int`, `Long`, `java.time.Duration`, and `java.time.Period` values --- .../jsoniter_scala/core/JsonWriter.scala | 111 ++++++++++------ .../jsoniter_scala/core/JsonWriter.scala | 118 +++++++++++------- .../jsoniter_scala/core/JsonWriter.scala | 110 ++++++++++------ 3 files changed, 216 insertions(+), 123 deletions(-) diff --git a/jsoniter-scala-core/js/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala b/jsoniter-scala-core/js/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala index 7923dc636..d8f0093d8 100644 --- a/jsoniter-scala-core/js/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala +++ b/jsoniter-scala-core/js/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala @@ -1157,12 +1157,18 @@ final class JsonWriter private[jsoniter_scala]( pos += 1 -exp } - count = - if (q0.toInt == q0) writePositiveInt(q0.toInt, pos, buf, ds) - else { - val q1 = q0 / 100000000 - write8Digits((q0 - q1 * 100000000).toInt, writePositiveInt(q1.toInt, pos, buf, ds), buf, ds) - } + var q = q0.toInt + var lastPos = pos + if (q0 == q) { + lastPos += digitCount(q) + count = lastPos + } else { + val q1 = q0 / 100000000 + q = q1.toInt + lastPos += digitCount(q) + count = write8Digits((q0 - q1 * 100000000).toInt, lastPos, buf, ds) + } + writePositiveIntDigits(q, lastPos, buf, ds) } } @@ -1314,12 +1320,18 @@ final class JsonWriter private[jsoniter_scala]( buf(pos) = '-' pos += 1 } - pos = - if (hours.toInt == hours) writePositiveInt(hours.toInt, pos, buf, ds) - else { - val q1 = hours / 100000000 - write8Digits((hours - q1 * 100000000).toInt, writePositiveInt(q1.toInt, pos, buf, ds), buf, ds) - } + var q = hours.toInt + var lastPos = pos + if (hours == q) { + lastPos += digitCount(hours) + pos = lastPos + } else { + val q1 = hours / 100000000 + q = q1.toInt + lastPos += digitCount(q1) + pos = write8Digits((hours - q1 * 100000000).toInt, lastPos, buf, ds) + } + writePositiveIntDigits(q, lastPos, buf, ds) buf(pos) = 'H' pos += 1 } @@ -1503,7 +1515,8 @@ final class JsonWriter private[jsoniter_scala]( pos += 2 147483648 } - pos = writePositiveInt(q0, pos, buf, ds) + pos += digitCount(q0) + writePositiveIntDigits(q0, pos, buf, ds) buf(pos) = b pos + 1 } @@ -1595,16 +1608,22 @@ final class JsonWriter private[jsoniter_scala]( if (year >= 0 && year < 10000) write4Digits(year, pos, buf, ds) else writeYearWithSign(year, pos, buf, ds) - private[this] def writeYearWithSign(year: Int, pos: Int, buf: Array[Byte], ds: Array[Short]): Int = { - var posYear = year + private[this] def writeYearWithSign(year: Int, p: Int, buf: Array[Byte], ds: Array[Short]): Int = { + var q0 = year + var pos = p var b: Byte = '+' - if (posYear < 0) { - posYear = -posYear + if (q0 < 0) { + q0 = -q0 b = '-' } buf(pos) = b - if (posYear < 10000) write4Digits(posYear, pos + 1, buf, ds) - else writePositiveInt(posYear, pos + 1, buf, ds) + pos += 1 + if (q0 < 10000) write4Digits(q0, pos, buf, ds) + else { + pos += digitCount(q0) + writePositiveIntDigits(q0, pos, buf, ds) + pos + } } private[this] def writeLocalTime(x: LocalTime, p: Int, buf: Array[Byte], ds: Array[Short]): Int = { @@ -1769,6 +1788,7 @@ final class JsonWriter private[jsoniter_scala]( private[this] def writeInt(x: Int): Unit = count = { var pos = ensureBufCapacity(11) // Int.MinValue.toString.length val buf = this.buf + val ds = digits val q0 = if (x >= 0) x else if (x != -2147483648) { @@ -1781,7 +1801,9 @@ final class JsonWriter private[jsoniter_scala]( pos += 2 147483648 } - writePositiveInt(q0, pos, buf, digits) + pos += digitCount(q0) + writePositiveIntDigits(q0, pos, buf, ds) + pos } private[this] def writeLong(x: Long): Unit = count = { @@ -1800,23 +1822,28 @@ final class JsonWriter private[jsoniter_scala]( pos += 2 223372036854775808L } - if (q0.toInt == q0) writePositiveInt(q0.toInt, pos, buf, ds) - else { + var q = q0.toInt + var lastPos = pos + if (q0 == q) { + lastPos += digitCount(q) + pos = lastPos + } else { val q1 = q0 / 100000000 - write8Digits((q0 - q1 * 100000000).toInt, { - if (q1.toInt == q1) writePositiveInt(q1.toInt, pos, buf, ds) - else { + pos = write8Digits((q0 - q1 * 100000000).toInt, { + q = q1.toInt + if (q1 == q) { + lastPos += digitCount(q) + lastPos + } else { val q2 = q1 / 100000000 - write8Digits((q1 - q2 * 100000000).toInt, writePositiveInt(q2.toInt, pos, buf, ds), buf, ds) + q = q2.toInt + lastPos += digitCount(q) + write8Digits((q1 - q2 * 100000000).toInt, lastPos, buf, ds) } }, buf, ds) } - } - - private[this] def writePositiveInt(q0: Int, pos: Int, buf: Array[Byte], ds: Array[Short]): Int = { - val lastPos = digitCount(q0) + pos - writePositiveIntDigits(q0, lastPos - 1, buf, ds) - lastPos + writePositiveIntDigits(q, lastPos, buf, ds) + pos } // Based on the amazing work of Raffaello Giulietti @@ -1929,7 +1956,7 @@ final class JsonWriter private[jsoniter_scala]( lastPos } else { pos += len - writePositiveIntDigits(m10, pos - 1, buf, ds) + writePositiveIntDigits(m10, pos, buf, ds) buf(pos) = '.' buf(pos + 1) = '0' pos + 2 @@ -2056,7 +2083,7 @@ final class JsonWriter private[jsoniter_scala]( lastPos } else { pos += len - writePositiveIntDigits(m10.toInt, pos - 1, buf, ds) + writePositiveIntDigits(m10.toInt, pos, buf, ds) buf(pos) = '.' buf(pos + 1) = '0' pos + 2 @@ -2170,19 +2197,21 @@ final class JsonWriter private[jsoniter_scala]( private[this] def writePositiveIntDigits(q: Int, p: Int, buf: Array[Byte], ds: Array[Short]): Unit = { var q0 = q var pos = p - while (q0 >= 100) { + while ({ + pos -= 2 + q0 >= 100 + }) { val q1 = q0 / 100 val d = ds(q0 - q1 * 100) - buf(pos - 1) = d.toByte - buf(pos) = (d >> 8).toByte + buf(pos) = d.toByte + buf(pos + 1) = (d >> 8).toByte q0 = q1 - pos -= 2 } - if (q0 < 10) buf(pos) = (q0 + '0').toByte + if (q0 < 10) buf(pos + 1) = (q0 + '0').toByte else { val d = ds(q0) - buf(pos - 1) = d.toByte - buf(pos) = (d >> 8).toByte + buf(pos) = d.toByte + buf(pos + 1) = (d >> 8).toByte } } diff --git a/jsoniter-scala-core/jvm/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala b/jsoniter-scala-core/jvm/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala index 990425659..7a726f84a 100644 --- a/jsoniter-scala-core/jvm/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala +++ b/jsoniter-scala-core/jvm/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala @@ -1012,12 +1012,19 @@ final class JsonWriter private[jsoniter_scala]( } ByteArrayAccess.setShort(buf, pos, m) pos += 2 - count = - if (q0.toInt == q0) writePositiveInt(q0.toInt, pos, buf, ds) - else { - val q1 = (q0 >> 8) * 1441151881 >> 49 // divide a small positive long by 100000000 - write8Digits(q0 - q1 * 100000000, writePositiveInt(q1.toInt, pos, buf, ds), buf, ds) - } + var q = 0 + var lastPos = pos + if (q0 < 100000000) { + q = q0.toInt + lastPos += digitCount(q0) + count = lastPos + } else { + val q1 = (q0 >> 8) * 1441151881 >> 49 // divide a small positive long by 100000000 + q = q1.toInt + lastPos += digitCount(q1) + count = write8Digits(q0 - q1 * 100000000, lastPos, buf, ds) + } + writePositiveIntDigits(q, lastPos, buf, ds) } } @@ -1150,12 +1157,19 @@ final class JsonWriter private[jsoniter_scala]( buf(pos) = '-' pos += 1 } - pos = - if (hours.toInt == hours) writePositiveInt(hours.toInt, pos, buf, ds) - else { - val q1 = Math.multiplyHigh(hours, 6189700196426901375L) >>> 25 // divide a positive long by 100000000 - write8Digits(hours - q1 * 100000000, writePositiveInt(q1.toInt, pos, buf, ds), buf, ds) - } + var q = 0 + var lastPos = pos + if (hours < 100000000) { + q = hours.toInt + lastPos += digitCount(hours) + pos = lastPos + } else { + val q1 = Math.multiplyHigh(hours, 6189700196426901375L) >>> 25 // divide a positive long by 100000000 + q = q1.toInt + lastPos += digitCount(q1) + pos = write8Digits(hours - q1 * 100000000, lastPos, buf, ds) + } + writePositiveIntDigits(q, lastPos, buf, ds) ByteArrayAccess.setShort(buf, pos, 0x2248) pos += 1 } @@ -1327,7 +1341,8 @@ final class JsonWriter private[jsoniter_scala]( pos += 2 147483648 } - pos = writePositiveInt(q0, pos, buf, ds) + pos += digitCount(q0) + writePositiveIntDigits(q0, pos, buf, ds) ByteArrayAccess.setShort(buf, pos, bs) pos + 1 } @@ -1427,16 +1442,22 @@ final class JsonWriter private[jsoniter_scala]( if (year >= 0 && year < 10000) write4Digits(year, pos, buf, ds) else writeYearWithSign(year, pos, buf, ds) - private[this] def writeYearWithSign(year: Int, pos: Int, buf: Array[Byte], ds: Array[Short]): Int = { - var posYear = year + private[this] def writeYearWithSign(year: Int, p: Int, buf: Array[Byte], ds: Array[Short]): Int = { + var q0 = year + var pos = p var b: Byte = '+' - if (posYear < 0) { - posYear = -posYear + if (q0 < 0) { + q0 = -q0 b = '-' } buf(pos) = b - if (posYear < 10000) write4Digits(posYear, pos + 1, buf, ds) - else writePositiveInt(posYear, pos + 1, buf, ds) + pos += 1 + if (q0 < 10000) write4Digits(q0, pos, buf, ds) + else { + pos += digitCount(q0) + writePositiveIntDigits(q0, pos, buf, ds) + pos + } } private[this] def writeLocalTime(x: LocalTime, pos: Int, buf: Array[Byte], ds: Array[Short]): Int = { @@ -1599,6 +1620,7 @@ final class JsonWriter private[jsoniter_scala]( private[this] def writeInt(x: Int): Unit = count = { var pos = ensureBufCapacity(11) // Int.MinValue.toString.length val buf = this.buf + val ds = digits val q0 = if (x >= 0) x else if (x != -2147483648) { @@ -1610,7 +1632,9 @@ final class JsonWriter private[jsoniter_scala]( pos += 2 147483648 } - writePositiveInt(q0, pos, buf, digits) + pos += digitCount(q0) + writePositiveIntDigits(q0, pos, buf, ds) + pos } private[this] def writeLong(x: Long): Unit = count = { @@ -1628,23 +1652,29 @@ final class JsonWriter private[jsoniter_scala]( pos += 2 223372036854775808L } - if (q0.toInt == q0) writePositiveInt(q0.toInt, pos, buf, ds) - else { + var q = 0 + var lastPos = pos + if (q0 < 100000000) { + q = q0.toInt + lastPos += digitCount(q0) + pos = lastPos + } else { val q1 = Math.multiplyHigh(q0, 6189700196426901375L) >>> 25 // divide a positive long by 100000000 - write8Digits(q0 - q1 * 100000000, { - if (q1.toInt == q1) writePositiveInt(q1.toInt, pos, buf, ds) - else { + pos = write8Digits(q0 - q1 * 100000000, { + if (q1 < 100000000) { + q = q1.toInt + lastPos += digitCount(q1) + lastPos + } else { val q2 = (q1 >> 8) * 1441151881 >> 49 // divide a small positive long by 100000000 - write8Digits(q1 - q2 * 100000000, writePositiveInt(q2.toInt, pos, buf, ds), buf, ds) + q = q2.toInt + lastPos += digitCount(q2) + write8Digits(q1 - q2 * 100000000, lastPos, buf, ds) } }, buf, ds) } - } - - private[this] def writePositiveInt(q0: Int, pos: Int, buf: Array[Byte], ds: Array[Short]): Int = { - val lastPos = digitCount(q0) + pos - writePositiveIntDigits(q0, lastPos - 1, buf, ds) - lastPos + writePositiveIntDigits(q, lastPos, buf, ds) + pos } // Based on the amazing work of Raffaello Giulietti @@ -1685,13 +1715,13 @@ final class JsonWriter private[jsoniter_scala]( cblCorr = 1 } e10 = e2 * 315653 - e2Corr >> 20 - val g1 = gs(e10 + 324 << 1) + 1 + val g = gs(e10 + 324 << 1) + 1 val h = (-e10 * 108853 >> 15) + e2 + 1 val cb = m2 << 2 val vbCorr = (m2 & 0x1) - 1 - val vb = rop(g1, cb << h) - val vbl = rop(g1, cb - cblCorr << h) + vbCorr - val vbr = rop(g1, cb + 2 << h) - vbCorr + val vb = rop(g, cb << h) + val vbl = rop(g, cb - cblCorr << h) + vbCorr + val vbr = rop(g, cb + 2 << h) - vbCorr if (vb < 400 || { m10 = (vb * 107374183L >> 32).toInt // divide a positive int by 40 val vb40 = m10 * 40 @@ -1751,7 +1781,7 @@ final class JsonWriter private[jsoniter_scala]( lastPos } else { pos += len - writePositiveIntDigits(m10, pos - 1, buf, ds) + writePositiveIntDigits(m10, pos, buf, ds) ByteArrayAccess.setShort(buf, pos, 0x302E) pos + 2 } @@ -1871,7 +1901,7 @@ final class JsonWriter private[jsoniter_scala]( lastPos } else { pos += len - writePositiveIntDigits(m10.toInt, pos - 1, buf, ds) + writePositiveIntDigits(m10.toInt, pos, buf, ds) ByteArrayAccess.setShort(buf, pos, 0x302E) pos + 2 } @@ -1941,14 +1971,16 @@ final class JsonWriter private[jsoniter_scala]( private[this] def writePositiveIntDigits(q: Int, p: Int, buf: Array[Byte], ds: Array[Short]): Unit = { var q0 = q var pos = p - while (q0 >= 100) { + while ({ + pos -= 2 + q0 >= 100 + }) { val q1 = (q0 * 1374389535L >> 37).toInt // divide a positive int by 100 - ByteArrayAccess.setShort(buf, pos - 1, ds(q0 - q1 * 100)) + ByteArrayAccess.setShort(buf, pos, ds(q0 - q1 * 100)) q0 = q1 - pos -= 2 } - if (q0 < 10) buf(pos) = (q0 + '0').toByte - else ByteArrayAccess.setShort(buf, pos - 1, ds(q0)) + if (q0 < 10) buf(pos + 1) = (q0 + '0').toByte + else ByteArrayAccess.setShort(buf, pos, ds(q0)) } private[this] def illegalNumberError(x: Double): Nothing = encodeError("illegal number: " + x) diff --git a/jsoniter-scala-core/native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala b/jsoniter-scala-core/native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala index cb1558213..2dd957485 100644 --- a/jsoniter-scala-core/native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala +++ b/jsoniter-scala-core/native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala @@ -1012,12 +1012,19 @@ final class JsonWriter private[jsoniter_scala]( } ByteArrayAccess.setShort(buf, pos, m) pos += 2 - count = - if (q0.toInt == q0) writePositiveInt(q0.toInt, pos, buf, ds) - else { - val q1 = (q0 >> 8) * 1441151881 >> 49 // divide a small positive long by 100000000 - write8Digits(q0 - q1 * 100000000, writePositiveInt(q1.toInt, pos, buf, ds), buf, ds) - } + var q = 0 + var lastPos = pos + if (q0 < 100000000) { + q = q0.toInt + lastPos += digitCount(q0) + count = lastPos + } else { + val q1 = (q0 >> 8) * 1441151881 >> 49 // divide a small positive long by 100000000 + q = q1.toInt + lastPos += digitCount(q1) + count = write8Digits(q0 - q1 * 100000000, lastPos, buf, ds) + } + writePositiveIntDigits(q, lastPos, buf, ds) } } @@ -1150,12 +1157,19 @@ final class JsonWriter private[jsoniter_scala]( buf(pos) = '-' pos += 1 } - pos = - if (hours.toInt == hours) writePositiveInt(hours.toInt, pos, buf, ds) - else { - val q1 = NativeMath.multiplyHigh(hours, 6189700196426901375L) >>> 25 // divide a positive long by 100000000 - write8Digits(hours - q1 * 100000000, writePositiveInt(q1.toInt, pos, buf, ds), buf, ds) - } + var q = 0 + var lastPos = pos + if (hours < 100000000) { + q = hours.toInt + lastPos += digitCount(hours) + pos = lastPos + } else { + val q1 = NativeMath.multiplyHigh(hours, 6189700196426901375L) >>> 25 // divide a positive long by 100000000 + q = q1.toInt + lastPos += digitCount(q1) + pos = write8Digits(hours - q1 * 100000000, lastPos, buf, ds) + } + writePositiveIntDigits(q, lastPos, buf, ds) ByteArrayAccess.setShort(buf, pos, 0x2248) pos += 1 } @@ -1327,7 +1341,8 @@ final class JsonWriter private[jsoniter_scala]( pos += 2 147483648 } - pos = writePositiveInt(q0, pos, buf, ds) + pos += digitCount(q0) + writePositiveIntDigits(q0, pos, buf, ds) ByteArrayAccess.setShort(buf, pos, bs) pos + 1 } @@ -1427,16 +1442,22 @@ final class JsonWriter private[jsoniter_scala]( if (year >= 0 && year < 10000) write4Digits(year, pos, buf, ds) else writeYearWithSign(year, pos, buf, ds) - private[this] def writeYearWithSign(year: Int, pos: Int, buf: Array[Byte], ds: Array[Short]): Int = { - var posYear = year + private[this] def writeYearWithSign(year: Int, p: Int, buf: Array[Byte], ds: Array[Short]): Int = { + var q0 = year + var pos = p var b: Byte = '+' - if (posYear < 0) { - posYear = -posYear + if (q0 < 0) { + q0 = -q0 b = '-' } buf(pos) = b - if (posYear < 10000) write4Digits(posYear, pos + 1, buf, ds) - else writePositiveInt(posYear, pos + 1, buf, ds) + pos += 1 + if (q0 < 10000) write4Digits(q0, pos, buf, ds) + else { + pos += digitCount(q0) + writePositiveIntDigits(q0, pos, buf, ds) + pos + } } private[this] def writeLocalTime(x: LocalTime, pos: Int, buf: Array[Byte], ds: Array[Short]): Int = { @@ -1599,6 +1620,7 @@ final class JsonWriter private[jsoniter_scala]( private[this] def writeInt(x: Int): Unit = count = { var pos = ensureBufCapacity(11) // Int.MinValue.toString.length val buf = this.buf + val ds = digits val q0 = if (x >= 0) x else if (x != -2147483648) { @@ -1610,7 +1632,9 @@ final class JsonWriter private[jsoniter_scala]( pos += 2 147483648 } - writePositiveInt(q0, pos, buf, digits) + pos += digitCount(q0) + writePositiveIntDigits(q0, pos, buf, ds) + pos } private[this] def writeLong(x: Long): Unit = count = { @@ -1628,23 +1652,29 @@ final class JsonWriter private[jsoniter_scala]( pos += 2 223372036854775808L } - if (q0.toInt == q0) writePositiveInt(q0.toInt, pos, buf, ds) - else { + var q = 0 + var lastPos = pos + if (q0 < 100000000) { + q = q0.toInt + lastPos += digitCount(q0) + pos = lastPos + } else { val q1 = NativeMath.multiplyHigh(q0, 6189700196426901375L) >>> 25 // divide a positive long by 100000000 - write8Digits(q0 - q1 * 100000000, { - if (q1.toInt == q1) writePositiveInt(q1.toInt, pos, buf, ds) - else { + pos = write8Digits(q0 - q1 * 100000000, { + if (q1 < 100000000) { + q = q1.toInt + lastPos += digitCount(q1) + lastPos + } else { val q2 = (q1 >> 8) * 1441151881 >> 49 // divide a small positive long by 100000000 - write8Digits(q1 - q2 * 100000000, writePositiveInt(q2.toInt, pos, buf, ds), buf, ds) + q = q2.toInt + lastPos += digitCount(q2) + write8Digits(q1 - q2 * 100000000, lastPos, buf, ds) } }, buf, ds) } - } - - private[this] def writePositiveInt(q0: Int, pos: Int, buf: Array[Byte], ds: Array[Short]): Int = { - val lastPos = digitCount(q0) + pos - writePositiveIntDigits(q0, lastPos - 1, buf, ds) - lastPos + writePositiveIntDigits(q, lastPos, buf, ds) + pos } // Based on the amazing work of Raffaello Giulietti @@ -1751,7 +1781,7 @@ final class JsonWriter private[jsoniter_scala]( lastPos } else { pos += len - writePositiveIntDigits(m10, pos - 1, buf, ds) + writePositiveIntDigits(m10, pos, buf, ds) ByteArrayAccess.setShort(buf, pos, 0x302E) pos + 2 } @@ -1871,7 +1901,7 @@ final class JsonWriter private[jsoniter_scala]( lastPos } else { pos += len - writePositiveIntDigits(m10.toInt, pos - 1, buf, ds) + writePositiveIntDigits(m10.toInt, pos, buf, ds) ByteArrayAccess.setShort(buf, pos, 0x302E) pos + 2 } @@ -1941,14 +1971,16 @@ final class JsonWriter private[jsoniter_scala]( private[this] def writePositiveIntDigits(q: Int, p: Int, buf: Array[Byte], ds: Array[Short]): Unit = { var q0 = q var pos = p - while (q0 >= 100) { + while ({ + pos -= 2 + q0 >= 100 + }) { val q1 = (q0 * 1374389535L >> 37).toInt // divide a positive int by 100 - ByteArrayAccess.setShort(buf, pos - 1, ds(q0 - q1 * 100)) + ByteArrayAccess.setShort(buf, pos, ds(q0 - q1 * 100)) q0 = q1 - pos -= 2 } - if (q0 < 10) buf(pos) = (q0 + '0').toByte - else ByteArrayAccess.setShort(buf, pos - 1, ds(q0)) + if (q0 < 10) buf(pos + 1) = (q0 + '0').toByte + else ByteArrayAccess.setShort(buf, pos, ds(q0)) } private[this] def illegalNumberError(x: Double): Nothing = encodeError("illegal number: " + x) From d4b4e1c9cc1b7b64e9484b4bddd12dc7018ccaaa Mon Sep 17 00:00:00 2001 From: plokhotnyuk Date: Wed, 11 Jan 2023 15:04:07 +0100 Subject: [PATCH 4/9] More efficient parsing of `java.time.Instant` values with 0 nanos --- .../plokhotnyuk/jsoniter_scala/core/JsonReader.scala | 3 ++- .../plokhotnyuk/jsoniter_scala/core/JsonReader.scala | 8 +++++--- .../plokhotnyuk/jsoniter_scala/core/JsonReader.scala | 8 +++++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/jsoniter-scala-core/js/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala b/jsoniter-scala-core/js/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala index 0df7b8a98..edb37b5fc 100644 --- a/jsoniter-scala-core/js/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala +++ b/jsoniter-scala-core/js/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala @@ -2023,7 +2023,8 @@ final class JsonReader private[jsoniter_scala]( if (isNeg) offsetTotal = -offsetTotal epochSecond -= offsetTotal } - Instant.ofEpochSecond(epochSecond, nano) + if (nano == 0) Instant.ofEpochSecond(epochSecond) + else Instant.ofEpochSecond(epochSecond, nano) } private[this] def parseEpochSecond(): Long = { diff --git a/jsoniter-scala-core/jvm/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala b/jsoniter-scala-core/jvm/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala index 24bb1ac93..0f26f4c33 100644 --- a/jsoniter-scala-core/jvm/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala +++ b/jsoniter-scala-core/jvm/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala @@ -2145,7 +2145,7 @@ final class JsonReader private[jsoniter_scala]( } private[this] def parseInstant(): Instant = { - val epochDaySeconds = parseEpochDaySeconds() + var epochSecond = parseEpochDaySeconds() var pos = head var buf = this.buf var secondOfDay = 0L @@ -2162,6 +2162,7 @@ final class JsonReader private[jsoniter_scala]( pos = head buf = this.buf } + epochSecond += secondOfDay var nano = 0 var nanoDigitWeight = -2 if (pos >= tail) { @@ -2222,9 +2223,10 @@ final class JsonReader private[jsoniter_scala]( } else offsetTotal = parseOffsetTotalWithDoubleQuotes(pos) if (offsetTotal > 64800) timezoneOffsetError() // 64800 == 18 * 60 * 60 if (isNeg) offsetTotal = -offsetTotal - secondOfDay -= offsetTotal + epochSecond -= offsetTotal } - Instant.ofEpochSecond(epochDaySeconds + secondOfDay, nano) + if (nano == 0) Instant.ofEpochSecond(epochSecond) + else Instant.ofEpochSecond(epochSecond, nano) } private[this] def parseEpochDaySeconds(): Long = { diff --git a/jsoniter-scala-core/native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala b/jsoniter-scala-core/native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala index 087768904..5b08a0210 100644 --- a/jsoniter-scala-core/native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala +++ b/jsoniter-scala-core/native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala @@ -2142,7 +2142,7 @@ final class JsonReader private[jsoniter_scala]( } private[this] def parseInstant(): Instant = { - val epochDaySeconds = parseEpochDaySeconds() + var epochSecond = parseEpochDaySeconds() var pos = head var buf = this.buf var secondOfDay = 0L @@ -2159,6 +2159,7 @@ final class JsonReader private[jsoniter_scala]( pos = head buf = this.buf } + epochSecond += secondOfDay var nano = 0 var nanoDigitWeight = -2 if (pos >= tail) { @@ -2219,9 +2220,10 @@ final class JsonReader private[jsoniter_scala]( } else offsetTotal = parseOffsetTotalWithDoubleQuotes(pos) if (offsetTotal > 64800) timezoneOffsetError() // 64800 == 18 * 60 * 60 if (isNeg) offsetTotal = -offsetTotal - secondOfDay -= offsetTotal + epochSecond -= offsetTotal } - Instant.ofEpochSecond(epochDaySeconds + secondOfDay, nano) + if (nano == 0) Instant.ofEpochSecond(epochSecond) + else Instant.ofEpochSecond(epochSecond, nano) } private[this] def parseEpochDaySeconds(): Long = { From c54db4d0f8618b5a4d7d94e3d05d5d17f2671980 Mon Sep 17 00:00:00 2001 From: Scala Steward Date: Wed, 11 Jan 2023 17:45:26 +0000 Subject: [PATCH 5/9] Update smithy4s-json to 0.17.2 --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 86c0acce2..5b530338b 100644 --- a/build.sbt +++ b/build.sbt @@ -231,7 +231,7 @@ lazy val `jsoniter-scala-benchmark` = crossProject(JVMPlatform, JSPlatform) "io.circe" %%% "circe-generic" % "0.14.3", "io.circe" %%% "circe-parser" % "0.14.3", "io.circe" %%% "circe-jawn" % "0.14.3", - "com.disneystreaming.smithy4s" %%% "smithy4s-json" % "0.17.1", + "com.disneystreaming.smithy4s" %%% "smithy4s-json" % "0.17.2", "org.json4s" %% "json4s-jackson" % "4.1.0-M2", "org.json4s" %% "json4s-native" % "4.1.0-M2", "com.rallyhealth" %% "weepickle-v1" % "1.8.0", From 42f5f920a8799b708cc3b41be57e66ef26780f4b Mon Sep 17 00:00:00 2001 From: plokhotnyuk Date: Thu, 12 Jan 2023 12:11:51 +0100 Subject: [PATCH 6/9] More efficient parsing of small `immutable.Seq` values --- .../jsoniter_scala/macros/JsonCodecMaker.scala | 8 ++++---- .../jsoniter_scala/macros/JsonCodecMaker.scala | 13 ++++++++++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/jsoniter-scala-macros/shared/src/main/scala-2/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala b/jsoniter-scala-macros/shared/src/main/scala-2/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala index 08b1dd434..dded4e80e 100644 --- a/jsoniter-scala-macros/shared/src/main/scala-2/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala +++ b/jsoniter-scala-macros/shared/src/main/scala-2/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala @@ -1173,7 +1173,7 @@ object JsonCodecMaker { else if (tpe <:< typeOf[BitSet]) withNullValueFor(tpe)(q"${scalaCollectionCompanion(tpe)}.empty") else if (tpe <:< typeOf[mutable.LongMap[_]]) q"${scalaCollectionCompanion(tpe)}.empty[${typeArg1(tpe)}]" else if (tpe <:< typeOf[::[_]]) q"null" - else if (tpe <:< typeOf[List[_]] || tpe =:= typeOf[Seq[_]]) q"_root_.scala.Nil" + else if (tpe <:< typeOf[List[_]] || tpe.typeSymbol == typeOf[Seq[_]].typeSymbol) q"_root_.scala.Nil" else if (tpe <:< typeOf[immutable.IntMap[_]] || tpe <:< typeOf[immutable.LongMap[_]] || tpe <:< typeOf[immutable.Seq[_]] || tpe <:< typeOf[Set[_]]) withNullValueFor(tpe) { q"${scalaCollectionCompanion(tpe)}.empty[${typeArg1(tpe)}]" @@ -1538,17 +1538,17 @@ object JsonCodecMaker { ..$readVal in.isNextToken(',') }) () - if (in.isCurrentToken(']')) x.toList.asInstanceOf[_root_.scala.collection.immutable.::[$tpe1]] + if (in.isCurrentToken(']')) x.result().asInstanceOf[_root_.scala.collection.immutable.::[$tpe1]] else in.arrayEndOrCommaError() } } else { if (default ne null) in.readNullOrTokenError(default, '[') else in.decodeError("expected non-empty JSON array") }""" - } else if (tpe <:< typeOf[List[_]] || tpe =:= typeOf[Seq[_]]) withDecoderFor(methodKey, default) { + } else if (tpe <:< typeOf[List[_]] || tpe.typeSymbol == typeOf[Seq[_]].typeSymbol) withDecoderFor(methodKey, default) { val tpe1 = typeArg1(tpe) genReadArray(q"{ val x = new _root_.scala.collection.mutable.ListBuffer[$tpe1] }", - genReadValForGrowable(tpe1 :: types, isStringified), q"x.toList") + genReadValForGrowable(tpe1 :: types, isStringified), q"x.result()") } else if (tpe <:< typeOf[mutable.Iterable[_] with mutable.Builder[_, _]] && !(tpe <:< typeOf[mutable.ArrayStack[_]])) withDecoderFor(methodKey, default) { //ArrayStack uses 'push' for '+=' in Scala 2.12.x val tpe1 = typeArg1(tpe) diff --git a/jsoniter-scala-macros/shared/src/main/scala-3/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala b/jsoniter-scala-macros/shared/src/main/scala-3/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala index 8453728b8..577eaf24c 100644 --- a/jsoniter-scala-macros/shared/src/main/scala-3/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala +++ b/jsoniter-scala-macros/shared/src/main/scala-3/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala @@ -1521,7 +1521,7 @@ object JsonCodecMaker { else if (tpe <:< TypeRepr.of[immutable.BitSet]) withNullValueFor(tpe)('{ immutable.BitSet.empty }.asExprOf[T]) else if (tpe <:< TypeRepr.of[collection.BitSet]) withNullValueFor(tpe)('{ collection.BitSet.empty }.asExprOf[T]) else if (tpe <:< TypeRepr.of[::[_]]) '{ null }.asExprOf[T] - else if (tpe <:< TypeRepr.of[List[_]] || tpe =:= TypeRepr.of[Seq[_]]) '{ Nil }.asExprOf[T] + else if (tpe <:< TypeRepr.of[List[_]] || tpe.typeSymbol == TypeRepr.of[Seq[_]].typeSymbol) '{ Nil }.asExprOf[T] else if (tpe <:< TypeRepr.of[collection.SortedSet[_]]) withNullValueFor(tpe) { val tpe1 = typeArg1(tpe) Apply(scalaCollectionEmptyNoArgs(tpe, tpe1), List(summonOrdering(tpe1))).asExprOf[T] @@ -2231,13 +2231,20 @@ object JsonCodecMaker { } }.asExprOf[T] } - } else if (tpe <:< TypeRepr.of[List[_]] || tpe =:= TypeRepr.of[Seq[_]]) withDecoderFor(methodKey, default, in) { (in, default) => + } else if (tpe <:< TypeRepr.of[List[_]]) withDecoderFor(methodKey, default, in) { (in, default) => val tpe1 = typeArg1(tpe) tpe1.asType match case '[t1] => genReadCollection('{ new mutable.ListBuffer[t1] }, x => genReadValForGrowable(tpe1 :: types, isStringified, x, in), - default.asExprOf[List[t1]], x => '{ $x.toList }, in).asExprOf[T] + default.asExprOf[List[t1]], x => '{ $x.result() }, in).asExprOf[T] + } else if (tpe.typeSymbol == TypeRepr.of[Seq[_]].typeSymbol) withDecoderFor(methodKey, default, in) { (in, default) => + val tpe1 = typeArg1(tpe) + tpe1.asType match + case '[t1] => + genReadCollection('{ new mutable.ListBuffer[t1] }, + x => genReadValForGrowable(tpe1 :: types, isStringified, x, in), + default.asExprOf[Seq[t1]], x => '{ $x.result() }, in).asExprOf[T] } else if (tpe <:< TypeRepr.of[mutable.ListBuffer[_]]) withDecoderFor(methodKey, default, in) { (in, default) => val tpe1 = typeArg1(tpe) tpe1.asType match From 941d82f94bb457b6a70f44b3d11a9ddaafe28267 Mon Sep 17 00:00:00 2001 From: plokhotnyuk Date: Thu, 12 Jan 2023 13:11:09 +0100 Subject: [PATCH 7/9] More efficient serialization of small `immutable.Vector` values --- .../plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala | 2 +- .../plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jsoniter-scala-macros/shared/src/main/scala-2/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala b/jsoniter-scala-macros/shared/src/main/scala-2/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala index dded4e80e..fe65102f2 100644 --- a/jsoniter-scala-macros/shared/src/main/scala-2/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala +++ b/jsoniter-scala-macros/shared/src/main/scala-2/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala @@ -1909,7 +1909,7 @@ object JsonCodecMaker { out.writeArrayEnd()""" } else if (tpe <:< typeOf[IndexedSeq[_]]) withEncoderFor(methodKey, m) { q"""out.writeArrayStart() - val l = x.size + val l = x.length if (l <= 32) { var i = 0 while (i < l) { diff --git a/jsoniter-scala-macros/shared/src/main/scala-3/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala b/jsoniter-scala-macros/shared/src/main/scala-3/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala index 577eaf24c..e06e590bf 100644 --- a/jsoniter-scala-macros/shared/src/main/scala-3/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala +++ b/jsoniter-scala-macros/shared/src/main/scala-3/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala @@ -2683,7 +2683,7 @@ object JsonCodecMaker { val tx = x.asExprOf[IndexedSeq[t1]] '{ $out.writeArrayStart() - val l = $tx.size + val l = $tx.length if (l <= 32) { var i = 0 while (i < l) { From 7d8e9de658689c777aff300705386b27eb907d5f Mon Sep 17 00:00:00 2001 From: plokhotnyuk Date: Thu, 12 Jan 2023 15:01:54 +0100 Subject: [PATCH 8/9] Code clean up --- .../github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala | 4 ++-- .../github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala | 4 ++-- .../github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/jsoniter-scala-core/js/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala b/jsoniter-scala-core/js/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala index edb37b5fc..664ce65c7 100644 --- a/jsoniter-scala-core/js/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala +++ b/jsoniter-scala-core/js/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala @@ -2920,7 +2920,7 @@ final class JsonReader private[jsoniter_scala]( val maxCharBufSize = config.maxCharBufSize if (charBufLen == maxCharBufSize) tooLongStringError() charBufLen = (-1 >>> Integer.numberOfLeadingZeros(charBufLen | required)) + 1 - if (Integer.compareUnsigned(charBufLen, maxCharBufSize) > 0) charBufLen = maxCharBufSize + if (charBufLen > maxCharBufSize || charBufLen < 0) charBufLen = maxCharBufSize charBuf = java.util.Arrays.copyOf(charBuf, charBufLen) charBufLen } @@ -3026,7 +3026,7 @@ final class JsonReader private[jsoniter_scala]( val maxBufSize = config.maxBufSize if (bufLen == maxBufSize) tooLongInputError() bufLen <<= 1 - if (Integer.compareUnsigned(bufLen, maxBufSize) > 0) bufLen = maxBufSize + if (bufLen > maxBufSize || bufLen < 0) bufLen = maxBufSize buf = java.util.Arrays.copyOf(buf, bufLen) } diff --git a/jsoniter-scala-core/jvm/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala b/jsoniter-scala-core/jvm/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala index 0f26f4c33..1e66ab521 100644 --- a/jsoniter-scala-core/jvm/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala +++ b/jsoniter-scala-core/jvm/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala @@ -3413,7 +3413,7 @@ final class JsonReader private[jsoniter_scala]( val maxCharBufSize = config.maxCharBufSize if (charBufLen == maxCharBufSize) tooLongStringError() charBufLen = (-1 >>> Integer.numberOfLeadingZeros(charBufLen | required)) + 1 - if (Integer.compareUnsigned(charBufLen, maxCharBufSize) > 0) charBufLen = maxCharBufSize + if (charBufLen > maxCharBufSize || charBufLen < 0) charBufLen = maxCharBufSize charBuf = java.util.Arrays.copyOf(charBuf, charBufLen) charBufLen } @@ -3519,7 +3519,7 @@ final class JsonReader private[jsoniter_scala]( val maxBufSize = config.maxBufSize if (bufLen == maxBufSize) tooLongInputError() bufLen <<= 1 - if (Integer.compareUnsigned(bufLen, maxBufSize) > 0) bufLen = maxBufSize + if (bufLen > maxBufSize || bufLen < 0) bufLen = maxBufSize buf = java.util.Arrays.copyOf(buf, bufLen) } diff --git a/jsoniter-scala-core/native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala b/jsoniter-scala-core/native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala index 5b08a0210..47ff83cfe 100644 --- a/jsoniter-scala-core/native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala +++ b/jsoniter-scala-core/native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala @@ -3410,7 +3410,7 @@ final class JsonReader private[jsoniter_scala]( val maxCharBufSize = config.maxCharBufSize if (charBufLen == maxCharBufSize) tooLongStringError() charBufLen = (-1 >>> Integer.numberOfLeadingZeros(charBufLen | required)) + 1 - if (Integer.compareUnsigned(charBufLen, maxCharBufSize) > 0) charBufLen = maxCharBufSize + if (charBufLen > maxCharBufSize || charBufLen < 0) charBufLen = maxCharBufSize charBuf = java.util.Arrays.copyOf(charBuf, charBufLen) charBufLen } @@ -3516,7 +3516,7 @@ final class JsonReader private[jsoniter_scala]( val maxBufSize = config.maxBufSize if (bufLen == maxBufSize) tooLongInputError() bufLen <<= 1 - if (Integer.compareUnsigned(bufLen, maxBufSize) > 0) bufLen = maxBufSize + if (bufLen > maxBufSize || bufLen < 0) bufLen = maxBufSize buf = java.util.Arrays.copyOf(buf, bufLen) } From cc4dd9de778d25a209c0cbe58b54e28ca701b63c Mon Sep 17 00:00:00 2001 From: plokhotnyuk Date: Thu, 12 Jan 2023 15:12:52 +0100 Subject: [PATCH 9/9] Setting version to 2.20.3 --- README.md | 6 +++--- jsoniter-scala-examples/build.sbt | 4 ++-- version.sbt | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f779be472..fca10f888 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Actions Build](https://github.com/plokhotnyuk/jsoniter-scala/workflows/build/badge.svg)](https://github.com/plokhotnyuk/jsoniter-scala/actions) [![Scala Steward](https://img.shields.io/badge/Scala_Steward-helping-brightgreen.svg?style=flat&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAQCAMAAAARSr4IAAAAVFBMVEUAAACHjojlOy5NWlrKzcYRKjGFjIbp293YycuLa3pYY2LSqql4f3pCUFTgSjNodYRmcXUsPD/NTTbjRS+2jomhgnzNc223cGvZS0HaSD0XLjbaSjElhIr+AAAAAXRSTlMAQObYZgAAAHlJREFUCNdNyosOwyAIhWHAQS1Vt7a77/3fcxxdmv0xwmckutAR1nkm4ggbyEcg/wWmlGLDAA3oL50xi6fk5ffZ3E2E3QfZDCcCN2YtbEWZt+Drc6u6rlqv7Uk0LdKqqr5rk2UCRXOk0vmQKGfc94nOJyQjouF9H/wCc9gECEYfONoAAAAASUVORK5CYII=)](https://scala-steward.org) [![Gitter Chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/plokhotnyuk/jsoniter-scala?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Maven Central](https://img.shields.io/badge/maven--central-2.20.2-blue.svg)](https://repo1.maven.org/maven2/com/github/plokhotnyuk/jsoniter-scala/) +[![Maven Central](https://img.shields.io/badge/maven--central-2.20.3-blue.svg)](https://repo1.maven.org/maven2/com/github/plokhotnyuk/jsoniter-scala/) Scala macros for compile-time generation of safe and ultra-fast JSON codecs. @@ -217,9 +217,9 @@ list of dependencies: ```sbt libraryDependencies ++= Seq( // Use the %%% operator instead of %% for Scala.js and Scala Native - "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-core" % "2.20.2", + "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-core" % "2.20.3", // Use the "provided" scope instead when the "compile-internal" scope is not supported - "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-macros" % "2.20.2" % "compile-internal" + "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-macros" % "2.20.3" % "compile-internal" ) ``` diff --git a/jsoniter-scala-examples/build.sbt b/jsoniter-scala-examples/build.sbt index ac0040446..e8372da44 100644 --- a/jsoniter-scala-examples/build.sbt +++ b/jsoniter-scala-examples/build.sbt @@ -13,9 +13,9 @@ val `jsoniter-scala-examples` = crossProject(JVMPlatform, NativePlatform) assembly / mainClass := Some("com.github.plokhotnyuk.jsoniter_scala.examples.Example01"), libraryDependencySchemes += "com.github.plokhotnyuk.jsoniter-scala" %%% "jsoniter-scala-core" % "always", libraryDependencies ++= Seq( - "com.github.plokhotnyuk.jsoniter-scala" %%% "jsoniter-scala-core" % "2.20.2", + "com.github.plokhotnyuk.jsoniter-scala" %%% "jsoniter-scala-core" % "2.20.3", // Use the "provided" scope instead when the "compile-internal" scope is not supported - "com.github.plokhotnyuk.jsoniter-scala" %%% "jsoniter-scala-macros" % "2.20.2" % "compile-internal" + "com.github.plokhotnyuk.jsoniter-scala" %%% "jsoniter-scala-macros" % "2.20.3" % "compile-internal" ) ) diff --git a/version.sbt b/version.sbt index b325a985c..4a8fc13cc 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -ThisBuild / version := "2.20.3-SNAPSHOT" +ThisBuild / version := "2.20.3"