Skip to content

Commit 6149c32

Browse files
committed
More efficient serialization of double and float values
1 parent 1186a5c commit 6149c32

File tree

3 files changed

+57
-78
lines changed
  • jsoniter-scala-core

3 files changed

+57
-78
lines changed

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

+19-26
Original file line numberDiff line numberDiff line change
@@ -2353,27 +2353,24 @@ final class JsonWriter private[jsoniter_scala](
23532353
val vb = rop(g, cb << h)
23542354
val vbl = rop(g, cb - cblCorr << h) + vbCorr
23552355
val vbr = rop(g, cb + 2 << h) - vbCorr
2356+
var diff = 0
23562357
if (vb < 400 || {
23572358
m10 = vb / 40
23582359
val vb40 = m10 * 40
2359-
val diff = vbl - vb40
2360-
(vb40 - vbr + 40 ^ diff) >= 0 || {
2361-
m10 += ~diff >>> 31
2362-
e10 += 1
2363-
false
2364-
}
2360+
diff = vbl - vb40
2361+
(vb40 - vbr + 40 ^ diff) >= 0
23652362
}) {
23662363
m10 = vb >> 2
23672364
val vb4 = m10 << 2
2368-
var diff = vbl - vb4
2365+
diff = vbl - vb4
23692366
if ((vb4 - vbr + 4 ^ diff) >= 0) diff = (vb & 0x3) + (m10 & 0x1) - 3
2370-
m10 += ~diff >>> 31
2371-
e10 -= e10Corr
2372-
}
2367+
} else e10Corr = -1
2368+
m10 += ~diff >>> 31
2369+
e10 -= e10Corr
23732370
}
2374-
val ds = digits
23752371
val len = digitCount(m10)
23762372
e10 += len - 1
2373+
val ds = digits
23772374
if (e10 < -3 || e10 >= 7) {
23782375
val lastPos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
23792376
buf(pos) = buf(pos + 1)
@@ -2399,9 +2396,8 @@ final class JsonWriter private[jsoniter_scala](
23992396
buf(pos + 2) = '0'
24002397
buf(pos + 3) = '0'
24012398
pos -= e10
2402-
val lastPos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
2399+
pos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
24032400
buf(dotPos) = '.'
2404-
pos = lastPos
24052401
} else if (e10 < len - 1) {
24062402
val lastPos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
24072403
val beforeDotPos = pos + e10
@@ -2466,6 +2462,7 @@ final class JsonWriter private[jsoniter_scala](
24662462
cblCorr = 1
24672463
}
24682464
e10 = e2 * 315653 - e2Corr >> 20
2465+
val gs = JsonWriter.gs
24692466
val i = e10 + 324 << 1
24702467
val g1 = gs(i)
24712468
val g0 = gs(i + 1)
@@ -2475,27 +2472,24 @@ final class JsonWriter private[jsoniter_scala](
24752472
val vb = rop(g1, g0, cb << h)
24762473
val vbl = rop(g1, g0, cb - cblCorr << h) + vbCorr
24772474
val vbr = rop(g1, g0, cb + 2 << h) - vbCorr
2475+
var diff = 0
24782476
if (vb < 400 || {
24792477
m10 = vb / 40
24802478
val vb40 = m10 * 40
2481-
val diff = (vbl - vb40).toInt
2482-
((vb40 - vbr).toInt + 40 ^ diff) >= 0 || {
2483-
m10 += ~diff >>> 31
2484-
e10 += 1
2485-
false
2486-
}
2479+
diff = (vbl - vb40).toInt
2480+
((vb40 - vbr).toInt + 40 ^ diff) >= 0
24872481
}) {
24882482
m10 = vb >> 2
24892483
val vb4 = m10 << 2
2490-
var diff = (vbl - vb4).toInt
2484+
diff = (vbl - vb4).toInt
24912485
if (((vb4 - vbr).toInt + 4 ^ diff) >= 0) diff = (vb.toInt & 0x3) + (m10.toInt & 0x1) - 3
2492-
m10 += ~diff >>> 31
2493-
e10 -= e10Corr
2494-
}
2486+
} else e10Corr = -1
2487+
m10 += ~diff >>> 31
2488+
e10 -= e10Corr
24952489
}
2496-
val ds = digits
24972490
val len = digitCount(m10)
24982491
e10 += len - 1
2492+
val ds = digits
24992493
if (e10 < -3 || e10 >= 7) {
25002494
val lastPos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
25012495
buf(pos) = buf(pos + 1)
@@ -2522,9 +2516,8 @@ final class JsonWriter private[jsoniter_scala](
25222516
buf(pos + 2) = '0'
25232517
buf(pos + 3) = '0'
25242518
pos -= e10
2525-
val lastPos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
2519+
pos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
25262520
buf(dotPos) = '.'
2527-
pos = lastPos
25282521
} else if (e10 < len - 1) {
25292522
val lastPos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
25302523
val beforeDotPos = pos + e10

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

+19-26
Original file line numberDiff line numberDiff line change
@@ -2191,27 +2191,24 @@ final class JsonWriter private[jsoniter_scala](
21912191
val vb = rop(g, cb << h)
21922192
val vbl = rop(g, cb - cblCorr << h) + vbCorr
21932193
val vbr = rop(g, cb + 2 << h) - vbCorr
2194+
var diff = 0
21942195
if (vb < 400 || {
21952196
m10 = (vb * 107374183L >> 32).toInt // divide a positive int by 40
21962197
val vb40 = m10 * 40
2197-
val diff = vbl - vb40
2198-
(vb40 - vbr + 40 ^ diff) >= 0 || {
2199-
m10 += ~diff >>> 31
2200-
e10 += 1
2201-
false
2202-
}
2198+
diff = vbl - vb40
2199+
(vb40 - vbr + 40 ^ diff) >= 0
22032200
}) {
22042201
m10 = vb >> 2
22052202
val vb4 = m10 << 2
2206-
var diff = vbl - vb4
2203+
diff = vbl - vb4
22072204
if ((vb4 - vbr + 4 ^ diff) >= 0) diff = (vb & 0x3) + (m10 & 0x1) - 3
2208-
m10 += ~diff >>> 31
2209-
e10 -= e10Corr
2210-
}
2205+
} else e10Corr = -1
2206+
m10 += ~diff >>> 31
2207+
e10 -= e10Corr
22112208
}
2212-
val ds = digits
22132209
val len = digitCount(m10.toLong)
22142210
e10 += len - 1
2211+
val ds = digits
22152212
if (e10 < -3 || e10 >= 7) {
22162213
val lastPos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
22172214
ByteArrayAccess.setShort(buf, pos, (buf(pos + 1) | 0x2E00).toShort)
@@ -2233,9 +2230,8 @@ final class JsonWriter private[jsoniter_scala](
22332230
val dotPos = pos + 1
22342231
ByteArrayAccess.setInt(buf, pos, 0x30303030)
22352232
pos -= e10
2236-
val lastPos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
2233+
pos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
22372234
buf(dotPos) = '.'
2238-
pos = lastPos
22392235
} else if (e10 < len - 1) {
22402236
val lastPos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
22412237
val bs = ByteArrayAccess.getLong(buf, pos)
@@ -2298,6 +2294,7 @@ final class JsonWriter private[jsoniter_scala](
22982294
cblCorr = 1
22992295
}
23002296
e10 = e2 * 315653 - e2Corr >> 20
2297+
val gs = JsonWriter.gs
23012298
val i = e10 + 324 << 1
23022299
val g1 = gs(i)
23032300
val g0 = gs(i + 1)
@@ -2307,27 +2304,24 @@ final class JsonWriter private[jsoniter_scala](
23072304
val vb = rop(g1, g0, cb << h)
23082305
val vbl = rop(g1, g0, cb - cblCorr << h) + vbCorr
23092306
val vbr = rop(g1, g0, cb + 2 << h) - vbCorr
2307+
var diff = 0
23102308
if (vb < 400 || {
23112309
m10 = Math.multiplyHigh(vb, 461168601842738792L) // divide a positive long by 40
23122310
val vb40 = m10 * 40
2313-
val diff = (vbl - vb40).toInt
2314-
((vb40 - vbr).toInt + 40 ^ diff) >= 0 || {
2315-
m10 += ~diff >>> 31
2316-
e10 += 1
2317-
false
2318-
}
2311+
diff = (vbl - vb40).toInt
2312+
((vb40 - vbr).toInt + 40 ^ diff) >= 0
23192313
}) {
23202314
m10 = vb >> 2
23212315
val vb4 = m10 << 2
2322-
var diff = (vbl - vb4).toInt
2316+
diff = (vbl - vb4).toInt
23232317
if (((vb4 - vbr).toInt + 4 ^ diff) >= 0) diff = (vb.toInt & 0x3) + (m10.toInt & 0x1) - 3
2324-
m10 += ~diff >>> 31
2325-
e10 -= e10Corr
2326-
}
2318+
} else e10Corr = -1
2319+
m10 += ~diff >>> 31
2320+
e10 -= e10Corr
23272321
}
2328-
val ds = digits
23292322
val len = digitCount(m10)
23302323
e10 += len - 1
2324+
val ds = digits
23312325
if (e10 < -3 || e10 >= 7) {
23322326
val lastPos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
23332327
ByteArrayAccess.setShort(buf, pos, (buf(pos + 1) | 0x2E00).toShort)
@@ -2350,9 +2344,8 @@ final class JsonWriter private[jsoniter_scala](
23502344
val dotPos = pos + 1
23512345
ByteArrayAccess.setInt(buf, pos, 0x30303030)
23522346
pos -= e10
2353-
val lastPos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
2347+
pos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
23542348
buf(dotPos) = '.'
2355-
pos = lastPos
23562349
} else if (e10 < len - 1) {
23572350
val lastPos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
23582351
val bs = ByteArrayAccess.getLong(buf, pos)

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

+19-26
Original file line numberDiff line numberDiff line change
@@ -2191,27 +2191,24 @@ final class JsonWriter private[jsoniter_scala](
21912191
val vb = rop(g, cb << h)
21922192
val vbl = rop(g, cb - cblCorr << h) + vbCorr
21932193
val vbr = rop(g, cb + 2 << h) - vbCorr
2194+
var diff = 0
21942195
if (vb < 400 || {
21952196
m10 = (vb * 107374183L >> 32).toInt // divide a positive int by 40
21962197
val vb40 = m10 * 40
2197-
val diff = vbl - vb40
2198-
(vb40 - vbr + 40 ^ diff) >= 0 || {
2199-
m10 += ~diff >>> 31
2200-
e10 += 1
2201-
false
2202-
}
2198+
diff = vbl - vb40
2199+
(vb40 - vbr + 40 ^ diff) >= 0
22032200
}) {
22042201
m10 = vb >> 2
22052202
val vb4 = m10 << 2
2206-
var diff = vbl - vb4
2203+
diff = vbl - vb4
22072204
if ((vb4 - vbr + 4 ^ diff) >= 0) diff = (vb & 0x3) + (m10 & 0x1) - 3
2208-
m10 += ~diff >>> 31
2209-
e10 -= e10Corr
2210-
}
2205+
} else e10Corr = -1
2206+
m10 += ~diff >>> 31
2207+
e10 -= e10Corr
22112208
}
2212-
val ds = digits
22132209
val len = digitCount(m10.toLong)
22142210
e10 += len - 1
2211+
val ds = digits
22152212
if (e10 < -3 || e10 >= 7) {
22162213
val lastPos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
22172214
ByteArrayAccess.setShort(buf, pos, (buf(pos + 1) | 0x2E00).toShort)
@@ -2233,9 +2230,8 @@ final class JsonWriter private[jsoniter_scala](
22332230
val dotPos = pos + 1
22342231
ByteArrayAccess.setInt(buf, pos, 0x30303030)
22352232
pos -= e10
2236-
val lastPos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
2233+
pos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
22372234
buf(dotPos) = '.'
2238-
pos = lastPos
22392235
} else if (e10 < len - 1) {
22402236
val lastPos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
22412237
val bs = ByteArrayAccess.getLong(buf, pos)
@@ -2298,6 +2294,7 @@ final class JsonWriter private[jsoniter_scala](
22982294
cblCorr = 1
22992295
}
23002296
e10 = e2 * 315653 - e2Corr >> 20
2297+
val gs = JsonWriter.gs
23012298
val i = e10 + 324 << 1
23022299
val g1 = gs(i)
23032300
val g0 = gs(i + 1)
@@ -2307,27 +2304,24 @@ final class JsonWriter private[jsoniter_scala](
23072304
val vb = rop(g1, g0, cb << h)
23082305
val vbl = rop(g1, g0, cb - cblCorr << h) + vbCorr
23092306
val vbr = rop(g1, g0, cb + 2 << h) - vbCorr
2307+
var diff = 0
23102308
if (vb < 400 || {
23112309
m10 = NativeMath.multiplyHigh(vb, 461168601842738792L) // divide a positive long by 40
23122310
val vb40 = m10 * 40
2313-
val diff = (vbl - vb40).toInt
2314-
((vb40 - vbr).toInt + 40 ^ diff) >= 0 || {
2315-
m10 += ~diff >>> 31
2316-
e10 += 1
2317-
false
2318-
}
2311+
diff = (vbl - vb40).toInt
2312+
((vb40 - vbr).toInt + 40 ^ diff) >= 0
23192313
}) {
23202314
m10 = vb >> 2
23212315
val vb4 = m10 << 2
2322-
var diff = (vbl - vb4).toInt
2316+
diff = (vbl - vb4).toInt
23232317
if (((vb4 - vbr).toInt + 4 ^ diff) >= 0) diff = (vb.toInt & 0x3) + (m10.toInt & 0x1) - 3
2324-
m10 += ~diff >>> 31
2325-
e10 -= e10Corr
2326-
}
2318+
} else e10Corr = -1
2319+
m10 += ~diff >>> 31
2320+
e10 -= e10Corr
23272321
}
2328-
val ds = digits
23292322
val len = digitCount(m10)
23302323
e10 += len - 1
2324+
val ds = digits
23312325
if (e10 < -3 || e10 >= 7) {
23322326
val lastPos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
23332327
ByteArrayAccess.setShort(buf, pos, (buf(pos + 1) | 0x2E00).toShort)
@@ -2350,9 +2344,8 @@ final class JsonWriter private[jsoniter_scala](
23502344
val dotPos = pos + 1
23512345
ByteArrayAccess.setInt(buf, pos, 0x30303030)
23522346
pos -= e10
2353-
val lastPos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
2347+
pos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
23542348
buf(dotPos) = '.'
2355-
pos = lastPos
23562349
} else if (e10 < len - 1) {
23572350
val lastPos = writeSignificantFractionDigits(m10, pos + len, pos, buf, ds)
23582351
val bs = ByteArrayAccess.getLong(buf, pos)

0 commit comments

Comments
 (0)