Skip to content

Commit d2d6366

Browse files
committed
Branchless sign serialization for time-zone offsets and BigDecimal exponents
1 parent 4c68b4c commit d2d6366

File tree

2 files changed

+18
-40
lines changed
  • jsoniter-scala-core

2 files changed

+18
-40
lines changed

jsoniter-scala-core/jvm/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,12 +1548,9 @@ final class JsonWriter private[jsoniter_scala](
15481548
var pos = ensureBufCapacity(12)
15491549
val buf = this.buf
15501550
val ds = digits
1551-
var m: Short = 0x2B45
1552-
if (exp < 0) {
1553-
m = 0x2D45
1554-
exp = -exp
1555-
}
1556-
ByteArrayAccess.setShort(buf, pos, m)
1551+
val s = exp >> 63
1552+
exp = (exp + s) ^ s
1553+
ByteArrayAccess.setShort(buf, pos, (0x2B45L - (s << 9)).toShort)
15571554
pos += 2
15581555
var q = exp
15591556
if (exp < 100000000L) {
@@ -1989,13 +1986,9 @@ final class JsonWriter private[jsoniter_scala](
19891986
pos += 3
19901987
} else {
19911988
val ds = digits
1992-
var m = 0x2230303A00002B22L
1993-
if (y < 0) {
1994-
y = -y
1995-
m = 0x2230303A00002D22L
1996-
}
1997-
y *= 37283 // Based on James Anhalt's algorithm: https://jk-jeon.github.io/posts/2022/02/jeaiii-algorithm/
1998-
m |= ds(y >>> 27) << 16
1989+
val s = y >> 31
1990+
y = ((y + s) ^ s) * 37283 // Based on James Anhalt's algorithm: https://jk-jeon.github.io/posts/2022/02/jeaiii-algorithm/
1991+
val m = ds(y >>> 27) << 16 | 0x2230303A00002B22L - (s << 9)
19991992
if ((y & 0x7FF8000) == 0) { // check if totalSeconds is divisible by 3600
20001993
ByteArrayAccess.setLong(buf, pos, m)
20011994
pos += 8
@@ -2086,13 +2079,9 @@ final class JsonWriter private[jsoniter_scala](
20862079
ByteArrayAccess.setShort(buf, pos, 0x225A)
20872080
pos + 2
20882081
} else {
2089-
var m = 0x2230303A00002BL
2090-
if (y < 0) {
2091-
y = -y
2092-
m = 0x2230303A00002DL
2093-
}
2094-
y *= 37283 // Based on James Anhalt's algorithm: https://jk-jeon.github.io/posts/2022/02/jeaiii-algorithm/
2095-
m |= ds(y >>> 27) << 8
2082+
val s = y >> 31
2083+
y = ((y + s) ^ s) * 37283 // Based on James Anhalt's algorithm: https://jk-jeon.github.io/posts/2022/02/jeaiii-algorithm/
2084+
val m = ds(y >>> 27) << 8 | 0x2230303A00002BL - (s << 1)
20962085
if ((y & 0x7FF8000) == 0) { // check if totalSeconds is divisible by 3600
20972086
ByteArrayAccess.setLong(buf, pos, m)
20982087
pos + 7

jsoniter-scala-core/native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,12 +1548,9 @@ final class JsonWriter private[jsoniter_scala](
15481548
var pos = ensureBufCapacity(12)
15491549
val buf = this.buf
15501550
val ds = digits
1551-
var m: Short = 0x2B45
1552-
if (exp < 0) {
1553-
m = 0x2D45
1554-
exp = -exp
1555-
}
1556-
ByteArrayAccess.setShort(buf, pos, m)
1551+
val s = exp >> 63
1552+
exp = (exp + s) ^ s
1553+
ByteArrayAccess.setShort(buf, pos, (0x2B45L - (s << 9)).toShort)
15571554
pos += 2
15581555
var q = exp
15591556
if (exp < 100000000L) {
@@ -1989,13 +1986,9 @@ final class JsonWriter private[jsoniter_scala](
19891986
pos += 3
19901987
} else {
19911988
val ds = digits
1992-
var m = 0x2230303A00002B22L
1993-
if (y < 0) {
1994-
y = -y
1995-
m = 0x2230303A00002D22L
1996-
}
1997-
y *= 37283 // Based on James Anhalt's algorithm: https://jk-jeon.github.io/posts/2022/02/jeaiii-algorithm/
1998-
m |= ds(y >>> 27) << 16
1989+
val s = y >> 31
1990+
y = ((y + s) ^ s) * 37283 // Based on James Anhalt's algorithm: https://jk-jeon.github.io/posts/2022/02/jeaiii-algorithm/
1991+
val m = ds(y >>> 27) << 16 | 0x2230303A00002B22L - (s << 9)
19991992
if ((y & 0x7FF8000) == 0) { // check if totalSeconds is divisible by 3600
20001993
ByteArrayAccess.setLong(buf, pos, m)
20011994
pos += 8
@@ -2086,13 +2079,9 @@ final class JsonWriter private[jsoniter_scala](
20862079
ByteArrayAccess.setShort(buf, pos, 0x225A)
20872080
pos + 2
20882081
} else {
2089-
var m = 0x2230303A00002BL
2090-
if (y < 0) {
2091-
y = -y
2092-
m = 0x2230303A00002DL
2093-
}
2094-
y *= 37283 // Based on James Anhalt's algorithm: https://jk-jeon.github.io/posts/2022/02/jeaiii-algorithm/
2095-
m |= ds(y >>> 27) << 8
2082+
val s = y >> 31
2083+
y = ((y + s) ^ s) * 37283 // Based on James Anhalt's algorithm: https://jk-jeon.github.io/posts/2022/02/jeaiii-algorithm/
2084+
val m = ds(y >>> 27) << 8 | 0x2230303A00002BL - (s << 1)
20962085
if ((y & 0x7FF8000) == 0) { // check if totalSeconds is divisible by 3600
20972086
ByteArrayAccess.setLong(buf, pos, m)
20982087
pos + 7

0 commit comments

Comments
 (0)