Skip to content

Commit e1567c1

Browse files
committed
More efficient array copying in writer & generated codecs for arrays, see details: https://shipilev.net/blog/2016/arrays-wisdom-ancients/
1 parent 979f4e3 commit e1567c1

File tree

2 files changed

+11
-15
lines changed

2 files changed

+11
-15
lines changed

core/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -345,9 +345,7 @@ final class JsonWriter private[jsoniter_scala](
345345
this.indention = 0
346346
isBufGrowingAllowed = true
347347
codec.encodeValue(x, this)
348-
val arr = new Array[Byte](count)
349-
System.arraycopy(buf, 0, arr, 0, arr.length)
350-
arr
348+
java.util.Arrays.copyOf(buf, count)
351349
} finally freeTooLongBuf()
352350

353351
private[jsoniter_scala] def write[@sp A](codec: JsonValueCodec[A], x: A, buf: Array[Byte], from: Int, config: WriterConfig): Int = {
@@ -1185,8 +1183,9 @@ final class JsonWriter private[jsoniter_scala](
11851183
else ((999999999 - q0) >>> 31) + 8
11861184

11871185
private[this] def writeByteArray(bs: Array[Byte], pos: Int): Int = {
1188-
System.arraycopy(bs, 0, buf, pos, bs.length)
1189-
pos + bs.length
1186+
val len = bs.length
1187+
System.arraycopy(bs, 0, buf, pos, len)
1188+
pos + len
11901189
}
11911190

11921191
private[this] def writeFloat(x: Float): Unit =
@@ -1222,8 +1221,9 @@ final class JsonWriter private[jsoniter_scala](
12221221
val newPos = flushBuffer(pos)
12231222
if (buf.length < pos + required) {
12241223
if (isBufGrowingAllowed) {
1225-
val bs = new Array[Byte](Math.max(buf.length << 1, pos + required))
1226-
System.arraycopy(buf, 0, bs, 0, buf.length)
1224+
val len = buf.length
1225+
val bs = new Array[Byte](Math.max(len << 1, pos + required))
1226+
System.arraycopy(buf, 0, bs, 0, len)
12271227
buf = bs
12281228
} else throw new ArrayIndexOutOfBoundsException("`buf` length exceeded")
12291229
}

macros/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -577,18 +577,14 @@ object JsonCodecMaker {
577577
q"""var x = new Array[$tpe1](16)
578578
var i = 0""",
579579
q"""if (i == x.length) {
580-
val y = new Array[$tpe1](i << 1)
581-
System.arraycopy(x, 0, y, 0, i)
582-
x = y
580+
val x1 = new Array[$tpe1](i << 1)
581+
System.arraycopy(x, 0, x1, 0, i)
582+
x = x1
583583
}
584584
x(i) = ${genReadVal(tpe1, nullValue(tpe1), isStringified)}
585585
i += 1""",
586586
q"""if (i == x.length) x
587-
else {
588-
val y = new Array[$tpe1](i)
589-
System.arraycopy(x, 0, y, 0, i)
590-
y
591-
}""")
587+
else java.util.Arrays.copyOf(x, i)""")
592588
} else if (tpe <:< typeOf[Enumeration#Value]) withDecoderFor(methodKey, default) {
593589
q"""if (in.isNextToken('"')) {
594590
in.rollbackToken()

0 commit comments

Comments
 (0)