@@ -125,26 +125,53 @@ type JsonValue =
125125
126126 serialize 0 x
127127
128+ // Optimized JSON string encoding with reduced allocations and bulk writing
128129 // Encode characters that are not valid in JS string. The implementation is based
129130 // on https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web/HttpUtility.cs
130131 static member internal JsonStringEncodeTo ( w : TextWriter ) ( value : string ) =
131132 if not ( String.IsNullOrEmpty value) then
133+ let mutable lastWritePos = 0
134+
132135 for i = 0 to value.Length - 1 do
133136 let c = value.[ i]
134137 let ci = int c
135138
136- if ci >= 0 && ci <= 7 || ci = 11 || ci >= 14 && ci <= 31 then
137- w.Write( " \\ u{0:x4}" , ci) |> ignore
138- else
139- match c with
140- | '\b' -> w.Write " \\ b"
141- | '\t' -> w.Write " \\ t"
142- | '\n' -> w.Write " \\ n"
143- | '\f' -> w.Write " \\ f"
144- | '\r' -> w.Write " \\ r"
145- | '"' -> w.Write " \\\" "
146- | '\\' -> w.Write " \\\\ "
147- | _ -> w.Write c
139+ let needsEscaping =
140+ ci >= 0 && ci <= 7
141+ || ci = 11
142+ || ci >= 14 && ci <= 31
143+ || c = '\b'
144+ || c = '\t'
145+ || c = '\n'
146+ || c = '\f'
147+ || c = '\r'
148+ || c = '"'
149+ || c = '\\'
150+
151+ if needsEscaping then
152+ // Write all accumulated unescaped characters in one operation using Substring
153+ if i > lastWritePos then
154+ w.Write( value.Substring( lastWritePos, i - lastWritePos))
155+
156+ // Write the escaped character
157+ if ci >= 0 && ci <= 7 || ci = 11 || ci >= 14 && ci <= 31 then
158+ w.Write( " \\ u{0:x4}" , ci) |> ignore
159+ else
160+ match c with
161+ | '\b' -> w.Write " \\ b"
162+ | '\t' -> w.Write " \\ t"
163+ | '\n' -> w.Write " \\ n"
164+ | '\f' -> w.Write " \\ f"
165+ | '\r' -> w.Write " \\ r"
166+ | '"' -> w.Write " \\\" "
167+ | '\\' -> w.Write " \\\\ "
168+ | _ -> w.Write c
169+
170+ lastWritePos <- i + 1
171+
172+ // Write any remaining unescaped characters
173+ if lastWritePos < value.Length then
174+ w.Write( value.Substring( lastWritePos))
148175
149176 member x.ToString ( saveOptions , ? indentationSpaces : int ) =
150177 let w = new StringWriter( CultureInfo.InvariantCulture)
0 commit comments