Skip to content

Commit 6af4f96

Browse files
committed
More efficient writing of Long, BigInt, and BigDecimal values using Scala.js
1 parent c5dddd9 commit 6af4f96

File tree

1 file changed

+24
-6
lines changed
  • jsoniter-scala-core/js/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core

1 file changed

+24
-6
lines changed

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

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2206,10 +2206,10 @@ final class JsonWriter private[jsoniter_scala](
22062206
}
22072207

22082208
private[this] def write18Digits(x: Long, pos: Int, buf: Array[Byte], ds: Array[Short]): Int = {
2209-
val q1 = x / 100000000
2210-
write8Digits((x - q1 * 100000000).toInt, {
2211-
val q2 = (q1 >>> 8) * 1441151881 >>> 49 // divide a small positive long by 100000000
2212-
write8Digits((q1 - q2 * 100000000).toInt, write2Digits(q2.toInt, pos, buf, ds), buf, ds)
2209+
val q1 = ((x >>> 8) * 2.56e-6).toLong
2210+
write8Digits((x - q1 * 100000000L).toInt, {
2211+
val q2 = (q1 >>> 8) * 1441151881L >>> 49 // divide a small positive long by 100000000
2212+
write8Digits((q1 - q2 * 100000000L).toInt, write2Digits(q2.toInt, pos, buf, ds), buf, ds)
22132213
}, buf, ds)
22142214
}
22152215

@@ -2280,11 +2280,29 @@ final class JsonWriter private[jsoniter_scala](
22802280
}
22812281
var q = q0.toInt
22822282
var lastPos = pos
2283+
var posCorr = 0
22832284
if (q0 == q) {
22842285
lastPos += digitCount(q)
22852286
pos = lastPos
22862287
} else {
2287-
val q1 = q0 / 100000000
2288+
if (q0 >= 1000000000000000000L) {
2289+
var z = q0
2290+
q0 = (q0 >>> 1) + (q0 >>> 2) // Based upon the divu10() code from Hacker's Delight 2nd Edition by Henry Warren
2291+
q0 += q0 >>> 4
2292+
q0 += q0 >>> 8
2293+
q0 += q0 >>> 16
2294+
q0 += q0 >>> 32
2295+
z -= q0 & 0xFFFFFFFFFFFFFFF8L
2296+
q0 >>>= 3
2297+
var r = (z - (q0 << 1)).toInt
2298+
if (r >= 10) {
2299+
q0 += 1
2300+
r -= 10
2301+
}
2302+
buf(pos + 18) = (r + '0').toByte
2303+
posCorr = 1
2304+
}
2305+
val q1 = ((q0 >>> 8) * 2.56e-6).toLong // divide a positive long by 100000000
22882306
q = q1.toInt
22892307
if (q1 == q) {
22902308
lastPos += digitCount(q)
@@ -2298,7 +2316,7 @@ final class JsonWriter private[jsoniter_scala](
22982316
pos = write8Digits((q0 - q1 * 100000000).toInt, pos, buf, ds)
22992317
}
23002318
writePositiveIntDigits(q, lastPos, buf, ds)
2301-
pos
2319+
pos + posCorr
23022320
}
23032321

23042322
// Based on the amazing work of Raffaello Giulietti

0 commit comments

Comments
 (0)