@@ -5,7 +5,7 @@ type JsonError* = object of ValueError
55const whiteSpace = {' ' , '\n ' , '\t ' , '\r ' }
66
77when defined (release):
8- {.push checks : off .}
8+ {.push checks : off , inline .}
99
1010type SomeTable * [K, V] = Table [K, V] | OrderedTable [K, V] |
1111 TableRef [K, V] | OrderedTableRef [K, V]
@@ -486,36 +486,45 @@ const lookup = block:
486486 s.add ($ i)
487487 s
488488
489+ proc dumpNumberSlow (s: var string , v: uint | uint8 | uint16 | uint32 | uint64 ) =
490+ s.add $ v.uint64
491+
492+ proc dumpNumberFast (s: var string , v: uint | uint8 | uint16 | uint32 | uint64 ) =
493+ # Its faster to not allocate a string for a number,
494+ # but to write it out the digits directly.
495+ if v == 0 :
496+ s.add '0'
497+ return
498+ # Max size of a uin64 number is 20 digits.
499+ var digits: array [20 , char ]
500+ var v = v
501+ var p = 0
502+ while v != 0 :
503+ # Its faster to look up 2 digits at a time, less int divisions.
504+ let idx = v mod 100
505+ digits[p] = lookup[idx* 2 + 1 ]
506+ inc p
507+ digits[p] = lookup[idx* 2 ]
508+ inc p
509+ v = v div 100
510+ var at = s.len
511+ if digits[p- 1 ] == '0' :
512+ dec p
513+ s.setLen (s.len + p)
514+ dec p
515+ while p >= 0 :
516+ s[at] = digits[p]
517+ dec p
518+ inc at
519+
489520proc dumpHook * (s: var string , v: uint | uint8 | uint16 | uint32 | uint64 ) =
490521 when nimvm :
491- s.add $ v. uint64
522+ s.dumpNumberSlow (v)
492523 else :
493- # Its faster to not allocate a string for a number,
494- # but to write it out the digits directly.
495- if v == 0 :
496- s.add '0'
497- return
498- # Max size of a uin64 number is 20 digits.
499- var digits: array [20 , char ]
500- var v = v
501- var p = 0
502- while v != 0 :
503- # Its faster to look up 2 digits at a time, less int divisions.
504- let idx = v mod 100
505- digits[p] = lookup[idx* 2 + 1 ]
506- inc p
507- digits[p] = lookup[idx* 2 ]
508- inc p
509- v = v div 100
510- var at = s.len
511- if digits[p- 1 ] == '0' :
512- dec p
513- s.setLen (s.len + p)
514- dec p
515- while p >= 0 :
516- s[at] = digits[p]
517- dec p
518- inc at
524+ when defined (js):
525+ s.dumpNumberSlow (v)
526+ else :
527+ s.dumpNumberFast (v)
519528
520529proc dumpHook * (s: var string , v: int | int8 | int16 | int32 | int64 ) =
521530 if v < 0 :
@@ -527,52 +536,61 @@ proc dumpHook*(s: var string, v: int|int8|int16|int32|int64) =
527536proc dumpHook * (s: var string , v: SomeFloat ) =
528537 s.add $ v
529538
539+ proc dumpStrSlow (s: var string , v: string ) =
540+ s.add '"'
541+ for c in v:
542+ case c:
543+ of '\\ ' : s.add r " \\ "
544+ of '\b ' : s.add r " \b "
545+ of '\f ' : s.add r " \f "
546+ of '\n ' : s.add r " \n "
547+ of '\r ' : s.add r " \r "
548+ of '\t ' : s.add r " \t "
549+ of '"' : s.add r " \"" "
550+ else :
551+ s.add c
552+ s.add '"'
553+
554+ proc dumpStrFast (s: var string , v: string ) =
555+ # Its faster to grow the string only once.
556+ # Then fill the string with pointers.
557+ # Then cap it off to right length.
558+ var at = s.len
559+ s.setLen (s.len + v.len* 2 + 2 )
560+
561+ var ss = cast [ptr UncheckedArray [char ]](s[0 ].addr )
562+ template add (ss: ptr UncheckedArray [char ], c: char ) =
563+ ss[at] = c
564+ inc at
565+ template add (ss: ptr UncheckedArray [char ], c1, c2: char ) =
566+ ss[at] = c1
567+ inc at
568+ ss[at] = c2
569+ inc at
570+
571+ ss.add '"'
572+ for c in v:
573+ case c:
574+ of '\\ ' : ss.add '\\ ' , '\\ '
575+ of '\b ' : ss.add '\\ ' , 'b'
576+ of '\f ' : ss.add '\\ ' , 'f'
577+ of '\n ' : ss.add '\\ ' , 'n'
578+ of '\r ' : ss.add '\\ ' , 'r'
579+ of '\t ' : ss.add '\\ ' , 't'
580+ of '"' : ss.add '\\ ' , '"'
581+ else :
582+ ss.add c
583+ ss.add '"'
584+ s.setLen (at)
585+
530586proc dumpHook * (s: var string , v: string ) =
531587 when nimvm :
532- s.add '"'
533- for c in v:
534- case c:
535- of '\\ ' : s.add r " \\ "
536- of '\b ' : s.add r " \b "
537- of '\f ' : s.add r " \f "
538- of '\n ' : s.add r " \n "
539- of '\r ' : s.add r " \r "
540- of '\t ' : s.add r " \t "
541- of '"' : s.add r " \"" "
542- else :
543- s.add c
544- s.add '"'
588+ s.dumpStrSlow (v)
545589 else :
546- # Its faster to grow the string only once.
547- # Then fill the string with pointers.
548- # Then cap it off to right length.
549- var at = s.len
550- s.setLen (s.len + v.len* 2 + 2 )
551-
552- var ss = cast [ptr UncheckedArray [char ]](s[0 ].addr )
553- template add (ss: ptr UncheckedArray [char ], c: char ) =
554- ss[at] = c
555- inc at
556- template add (ss: ptr UncheckedArray [char ], c1, c2: char ) =
557- ss[at] = c1
558- inc at
559- ss[at] = c2
560- inc at
561-
562- ss.add '"'
563- for c in v:
564- case c:
565- of '\\ ' : ss.add '\\ ' , '\\ '
566- of '\b ' : ss.add '\\ ' , 'b'
567- of '\f ' : ss.add '\\ ' , 'f'
568- of '\n ' : ss.add '\\ ' , 'n'
569- of '\r ' : ss.add '\\ ' , 'r'
570- of '\t ' : ss.add '\\ ' , 't'
571- of '"' : ss.add '\\ ' , '"'
572- else :
573- ss.add c
574- ss.add '"'
575- s.setLen (at)
590+ when defined (js):
591+ s.dumpStrSlow (v)
592+ else :
593+ s.dumpStrFast (v)
576594
577595template dumpKey (s: var string , v: string ) =
578596 const v2 = v.toJson () & " :"
0 commit comments