Here is my version:
    
    
    # Compile and run with 'nim c -r -d:useRealtimeGC -d:release main.nim'
    
    import strutils
    import times
    
    const
      windowSize = 200000
      msgCount   = 1000000
    
    type
      Msg = seq[byte]
      Buffer = seq[Msg]
    
    var worst: float
    
    proc mkMessage(n: int): Msg =
      result = newSeq[byte](1024)
      for i in 0 .. <result.len:
        result[i] = byte(n)
    
    proc pushMsg(b: var Buffer, highID: int) =
      let start = epochTime()
      
      let m = mkMessage(highID)
      b[highID mod windowSize] = m
      
      GC_step(10_000) # 10ms
      
      let elapsed = epochTime() - start
      if elapsed > worst:
        worst = elapsed
    
    proc main() =
      GC_disable()
      
      var b = newSeq[Msg](windowSize)
      for i in 0 .. <msgCount:
        pushMsg(b, i)
      
      let worst_ms = formatFloat(worst * 1000, format=ffDecimal, precision=2)
      echo("Worst push time: ", worst_ms, "ms")
      
      echo(GC_getStatistics())
    
    when isMainModule:
      main()
    

Things i've changed:

  * Removed extraneous spaces after `(` and before `)`.
  * Rewrote code to make it more idiomatic.
    * Using `seq[byte]` instead of `ref array[1024, byte]` (this is not 
idiomatic at all)
  * Switched from `cpuTime` to `epochTime`, the former only measures CPU 
time(!).
  * Added some real-time GC API calls.



Strangely, switching to `seq` causes an overall slowdown (the max push time is 
unaffected, but the application takes longer to complete).

On my machine the typical worst push time is 10ms, both for my version of the 
code and yours. The addition of `GC_step` doesn't really help, but it is nice 
to show off. Go 1.5 (maybe I should upgrade) gets 8ms. So Nim is 2ms off, which 
isn't bad. As pointed out by /u/matthieum on Reddit, the power of Nim is the 
fact that you can specify exactly where the GC should run (as I've done using 
the `GC_step` call).

BTW, `stack` isn't a GC. 

Reply via email to