##// END OF EJS Templates
JSONWriter improvements
cin -
r150:3258399cba83 v2
parent child
Show More
@@ -2,6 +2,7
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.IO;
3 using System.IO;
4 using System.Globalization;
4 using System.Globalization;
5 using System.Diagnostics;
5
6
6 namespace Implab.JSON {
7 namespace Implab.JSON {
7 public class JSONWriter {
8 public class JSONWriter {
@@ -12,10 +13,15 namespace Implab.JSON {
12 Stack<Context> m_contextStack = new Stack<Context>();
13 Stack<Context> m_contextStack = new Stack<Context>();
13 Context m_context;
14 Context m_context;
14
15
16 const int BUFFER_SIZE = 64;
17
15 TextWriter m_writer;
18 TextWriter m_writer;
16 readonly bool m_indent = true;
19 readonly bool m_indent = true;
17 readonly int m_indentSize = 4;
20 readonly int m_indentSize = 4;
21 readonly char[] m_buffer = new char[BUFFER_SIZE];
22 int m_bufferPos;
18
23
24 static readonly char [] _hex = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
19 static readonly char [] _escapeBKS,
25 static readonly char [] _escapeBKS,
20 _escapeFWD,
26 _escapeFWD,
21 _escapeCR,
27 _escapeCR,
@@ -211,7 +217,13 namespace Implab.JSON {
211 void Write(bool value) {
217 void Write(bool value) {
212 m_writer.Write(value ? "true" : "false");
218 m_writer.Write(value ? "true" : "false");
213 }
219 }
214
220
221 void FlushBuffer() {
222 if (m_bufferPos > 0) {
223 m_writer.Write(m_buffer, 0, m_bufferPos);
224 m_bufferPos = 0;
225 }
226 }
215
227
216 void Write(string value) {
228 void Write(string value) {
217 if (value == null) {
229 if (value == null) {
@@ -219,46 +231,73 namespace Implab.JSON {
219 return;
231 return;
220 }
232 }
221
233
234 Debug.Assert(m_bufferPos == 0);
235
222 var chars = value.ToCharArray();
236 var chars = value.ToCharArray();
223 m_writer.Write('"');
237 m_buffer[m_bufferPos++] = '"';
224
238
225 // Analysis disable once ForCanBeConvertedToForeach
239 // Analysis disable once ForCanBeConvertedToForeach
226 for (int i = 0; i < chars.Length; i++) {
240 for (int i = 0; i < chars.Length; i++) {
227 var ch = chars[i];
241 var ch = chars[i];
228
242
243 char[] escapeSeq;
244
229 switch (ch) {
245 switch (ch) {
230 case '\b':
246 case '\b':
231 m_writer.Write(_escapeBKS);
247 escapeSeq = _escapeBKS;
232 break;
248 break;
233 case '\f':
249 case '\f':
234 m_writer.Write(_escapeFWD);
250 escapeSeq = _escapeFWD;
235 break;
251 break;
236 case '\r':
252 case '\r':
237 m_writer.Write(_escapeCR);
253 escapeSeq = _escapeCR;
238 break;
254 break;
239 case '\n':
255 case '\n':
240 m_writer.Write(_escapeNL);
256 escapeSeq = _escapeNL;
241 break;
257 break;
242 case '\t':
258 case '\t':
243 m_writer.Write(_escapeTAB);
259 escapeSeq = _escapeTAB;
244 break;
260 break;
245 case '\\':
261 case '\\':
246 m_writer.Write(_escapeBSLASH);
262 escapeSeq = _escapeBSLASH;
247 break;
263 break;
248 case '"':
264 case '"':
249 m_writer.Write(_escapeQ);
265 escapeSeq = _escapeQ;
250 break;
266 break;
251 default:
267 default:
252 if (ch < 0x20) {
268 if (ch < 0x20) {
253 m_writer.Write("\\u00{0:x2}",(int)ch);
269 if (m_bufferPos + 6 > BUFFER_SIZE)
270 FlushBuffer();
271
272 m_buffer[m_bufferPos++] = '\\';
273 m_buffer[m_bufferPos++] = 'u';
274 m_buffer[m_bufferPos++] = '0';
275 m_buffer[m_bufferPos++] = '0';
276 m_buffer[m_bufferPos++] = _hex[ch >> 4 & 0xf];
277 m_buffer[m_bufferPos++] = _hex[ch & 0xf];
278
254 } else {
279 } else {
255 m_writer.Write(ch);
280 if (m_bufferPos >= BUFFER_SIZE)
281 FlushBuffer();
282 m_buffer[m_bufferPos++] = ch;
256 }
283 }
257 break;
284 continue;
258 }
285 }
286
287 if (m_bufferPos + escapeSeq.Length > BUFFER_SIZE)
288 FlushBuffer();
289
290 Array.Copy(escapeSeq, 0, m_buffer, m_bufferPos, escapeSeq.Length);
291 m_bufferPos += escapeSeq.Length;
292
259 }
293 }
260
294
261 m_writer.Write('"');
295 if (m_bufferPos >= BUFFER_SIZE)
296 FlushBuffer();
297
298 m_buffer[m_bufferPos++] = '"';
299
300 FlushBuffer();
262 }
301 }
263
302
264 void Write(double value) {
303 void Write(double value) {
@@ -5,6 +5,8 using Implab;
5 using System.Collections.Generic;
5 using System.Collections.Generic;
6 using System.Collections.Concurrent;
6 using System.Collections.Concurrent;
7 using System.Threading;
7 using System.Threading;
8 using Implab.JSON;
9 using System.IO;
8
10
9 namespace MonoPlay {
11 namespace MonoPlay {
10 class MainClass {
12 class MainClass {
@@ -16,25 +18,27 namespace MonoPlay {
16
18
17 var t1 = Environment.TickCount;
19 var t1 = Environment.TickCount;
18
20
19 for (int i = 0; i < 10000000; i++) {
21 for(int i =0; i < 1000000; i++)
20
22 using (var tw = new StringWriter()) {
21 var p = new Promise<int>();
23 var jw = new JSONWriter(tw);
22 p.On(HandleResult);
24
23 p.Resolve(i);
25 jw.WriteValue("\r\nhere\tvalue\u0002\u0003");
26
27 //Console.WriteLine(tw);
24 }
28 }
25
29
30
31
26 var t2 = Environment.TickCount;
32 var t2 = Environment.TickCount;
27 Console.WriteLine("done: {0} ms, {1:.00} Mb, {2} GC", t2 - t1, GC.GetTotalMemory(false) / (1024*1024), GC.CollectionCount(0) );
33 Console.WriteLine("done: {0} ms, {1:.00} Mb, {2} GC", t2 - t1, GC.GetTotalMemory(false) / (1024*1024), GC.CollectionCount(0) );
28
34
29 }
35 }
30
36
31 static void HandleAction ()
37 static void DoTest() {
32 {
38
33
39
40
34 }
41 }
35
42
36 static void HandleResult(int x) {
37
38 }
39 }
43 }
40 }
44 }
General Comments 0
You need to be logged in to leave comments. Login now