Skip to content

Commit 6de0c92

Browse files
authored
Use a fast path for more efficient encoding of strings that do not require encoding (zio#1234)
1 parent 681aef7 commit 6de0c92

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

zio-json/shared/src/main/scala/zio/json/JsonEncoder.scala

+23-2
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,26 @@ object JsonEncoder extends GeneratedTupleEncoders with EncoderLowPriority1 with
120120

121121
override def unsafeEncode(a: String, indent: Option[Int], out: Write): Unit = {
122122
out.write('"')
123+
val len = a.length
123124
var i = 0
125+
while (i < len) {
126+
val c = a.charAt(i)
127+
i += 1
128+
if (c == '"' || c == '\\' || c < ' ') {
129+
writeEncoded(a, out)
130+
return
131+
}
132+
}
133+
out.write(a)
134+
out.write('"')
135+
}
136+
137+
override final def toJsonAST(a: String): Either[String, Json] =
138+
Right(Json.Str(a))
139+
140+
private[this] def writeEncoded(a: String, out: Write): Unit = {
124141
val len = a.length
142+
var i = 0
125143
while (i < len) {
126144
(a.charAt(i): @switch) match {
127145
case '"' => out.write("\\\"")
@@ -140,8 +158,6 @@ object JsonEncoder extends GeneratedTupleEncoders with EncoderLowPriority1 with
140158
out.write('"')
141159
}
142160

143-
override final def toJsonAST(a: String): Either[String, Json] =
144-
Right(Json.Str(a))
145161
}
146162

147163
implicit val char: JsonEncoder[Char] = new JsonEncoder[Char] {
@@ -151,6 +167,11 @@ object JsonEncoder extends GeneratedTupleEncoders with EncoderLowPriority1 with
151167
(a: @switch) match {
152168
case '"' => out.write("\\\"")
153169
case '\\' => out.write("\\\\")
170+
case '\b' => out.write("\\b")
171+
case '\f' => out.write("\\f")
172+
case '\n' => out.write("\\n")
173+
case '\r' => out.write("\\r")
174+
case '\t' => out.write("\\t")
154175
case c =>
155176
if (c < ' ') out.write("\\u%04x".format(c.toInt))
156177
else out.write(c)

0 commit comments

Comments
 (0)