Wow I love optimizing things. Most of the time is taken up but the float to 
string conversion. I tried to eliminate all of the unnecessary copies, index 
checks and buffer grows:
    
    
    name ............................... min time      avg time    std dv   runs
    var str ........................... 11.591 ms     11.807 ms    ±0.133   x423
    orignal ........................... 12.601 ms     12.863 ms    ±0.171   x388
    
    
    Run

I only managed to eliminate 1ms, it's not worth the complexity, It's all in the 
`c_sprintf`. Because you are dealing with graphics maybe there is a suboptimal 
but a faster float writer. But still it will not be zero time it will always be 
up to the float to string converter.
    
    
    import vmath, benchy
    
    var vecArr: seq[Vec3]
    
    for i in 0 ..< 10000:
      vecArr.add(vec3(i.float, i.float*2, 1))
    
    {.push checks:off.}
    
    proc c_sprintf(buf, fmt: cstring): int {.importc:"sprintf", header: 
"<stdio.h>", varargs.}
    
    proc addFloat32(s: var string, i: var int, f: float32) {.inline,.} =
      i += c_sprintf(s[i].addr, "%f", f)
    
    proc addChar(s: var string, i: var int, c: char) {.inline.} =
      s[i] = c
      inc i
    
    timeIt "var str":
      var
        s = ""
        i = 0
      for j in 0 ..< vecArr.len:
        s.setLen(i + 128)
        let a = vecArr[j]
        addChar(s, i, '<')
        addFloat32(s, i, a.x)
        addChar(s, i, ',')
        addFloat32(s, i, a.y)
        addChar(s, i, ',')
        addFloat32(s, i, a.z)
        addChar(s, i, '>')
      s.setLen(i)
      keep(s)
    {.pop.}
    
    
    # proc `$`*(x: float): string {.magic: "FloatToStr", noSideEffect.}
    #   ## The stringify operator for a float argument. Returns `x`
    #   ## converted to a decimal string.
    
    # proc floatToStr(f: float64): string =
    #   var buffer: array[128, char]
    #   c_sprintf(addr buffer, "%.16e", f)
    #   result = ""
    #   for ch in buffer:
    #     if ch == '\0':
    #       return
    #     add(result, ch)
    
    timeIt "orignal":
      proc povVec3(a: Vec3): string {.inline.} =
        "<" & $a.x & "," & $a.y & "," & $a.z & ">"
      var vecStr = ""
      for i in 0 ..< vecArr.len:
        vecStr.add(povVec3(vecArr[i]))
      keep(vecStr)
    
    
    Run

Reply via email to