string.add for floats and ints for more performance (JS not yet supported)

This commit is contained in:
Andreas Rumpf 2016-11-21 13:53:55 +01:00
commit 9ca15ad369

View file

@ -263,27 +263,32 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
result.len = newLen result.len = newLen
# --------------- other string routines ---------------------------------- # --------------- other string routines ----------------------------------
proc nimIntToStr(x: int): string {.compilerRtl.} = proc add*(result: var string; x: int64) =
result = newString(sizeof(x)*4) let base = result.len
setLen(result, base + sizeof(x)*4)
var i = 0 var i = 0
var y = x var y = x
while true: while true:
var d = y div 10 var d = y div 10
result[i] = chr(abs(int(y - d*10)) + ord('0')) result[base+i] = chr(abs(int(y - d*10)) + ord('0'))
inc(i) inc(i)
y = d y = d
if y == 0: break if y == 0: break
if x < 0: if x < 0:
result[i] = '-' result[base+i] = '-'
inc(i) inc(i)
setLen(result, i) setLen(result, base+i)
# mirror the string: # mirror the string:
for j in 0..i div 2 - 1: for j in 0..i div 2 - 1:
swap(result[j], result[i-j-1]) swap(result[base+j], result[base+i-j-1])
proc nimFloatToStr(f: float): string {.compilerproc.} = proc nimIntToStr(x: int): string {.compilerRtl.} =
result = newStringOfCap(sizeof(x)*4)
result.add x
proc add*(result: var string; x: float) =
var buf: array[0..64, char] var buf: array[0..64, char]
var n: int = c_sprintf(buf, "%.16g", f) var n: int = c_sprintf(buf, "%.16g", x)
var hasDot = false var hasDot = false
for i in 0..n-1: for i in 0..n-1:
if buf[i] == ',': if buf[i] == ',':
@ -298,14 +303,18 @@ proc nimFloatToStr(f: float): string {.compilerproc.} =
# On Windows nice numbers like '1.#INF', '-1.#INF' or '1.#NAN' are produced. # On Windows nice numbers like '1.#INF', '-1.#INF' or '1.#NAN' are produced.
# We want to get rid of these here: # We want to get rid of these here:
if buf[n-1] in {'n', 'N'}: if buf[n-1] in {'n', 'N'}:
result = "nan" result.add "nan"
elif buf[n-1] == 'F': elif buf[n-1] == 'F':
if buf[0] == '-': if buf[0] == '-':
result = "-inf" result.add "-inf"
else: else:
result = "inf" result.add "inf"
else: else:
result = $buf result.add buf
proc nimFloatToStr(f: float): string {.compilerproc.} =
result = newStringOfCap(8)
result.add f
proc c_strtod(buf: cstring, endptr: ptr cstring): float64 {. proc c_strtod(buf: cstring, endptr: ptr cstring): float64 {.
importc: "strtod", header: "<stdlib.h>", noSideEffect.} importc: "strtod", header: "<stdlib.h>", noSideEffect.}
@ -469,22 +478,8 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
number = c_strtod(t, nil) number = c_strtod(t, nil)
proc nimInt64ToStr(x: int64): string {.compilerRtl.} = proc nimInt64ToStr(x: int64): string {.compilerRtl.} =
result = newString(sizeof(x)*4) result = newStringOfCap(sizeof(x)*4)
var i = 0 result.add x
var y = x
while true:
var d = y div 10
result[i] = chr(abs(int(y - d*10)) + ord('0'))
inc(i)
y = d
if y == 0: break
if x < 0:
result[i] = '-'
inc(i)
setLen(result, i)
# mirror the string:
for j in 0..i div 2 - 1:
swap(result[j], result[i-j-1])
proc nimBoolToStr(x: bool): string {.compilerRtl.} = proc nimBoolToStr(x: bool): string {.compilerRtl.} =
return if x: "true" else: "false" return if x: "true" else: "false"