Ok, on my Mac this one produces better timings.
```nim
# Compile and run with 'nim c -r -d:useRealtimeGC -d:release main.nim'
import strutils
#import times
include "$lib/system/timers"
const
windowSize = 200000
msgCount = 1000000
type
Msg = seq[byte]
Buffer = seq[Msg]
var worst: Nanos
proc mkMessage(n: int): Msg =
result = newSeq[byte](1024)
for i in 0 .. <result.len:
result[i] = byte(n)
proc pushMsg0(b: var Buffer, highID: int) =
let m = mkMessage(highID)
shallowCopy(b[highID mod windowSize], m)
proc pushMsg1(b: var Buffer, highID: int) =
let start = getTicks()
let m = mkMessage(highID)
# seqs copy, we don't want a copy here, so I used 'shallowCopy'.
# Alternatively the 'ref array' version could be used.
# Note that due to Nim's design we could also *re-use* the memory
# completely, eliminating the GC runs but this would make this
# benchmark pointless.
shallowCopy(b[highID mod windowSize], m)
#GC_step(500) # 0.5ms, but GC never takes this long.
let elapsed = getTicks() - start
if elapsed > worst:
worst = elapsed
proc main() =
#GC_disable()
# The MS backup collector is only required for cylic data structures,
# but in this program we generate no cycles. Nim allows us to specify this
# behaviour directly, so IMO it's fair to disable it. Nim's GC docs also
# mention this fact, it's not undocumented voodoo:
GC_disableMarkAndSweep()
GC_setMaxPause(300)
var b = newSeq[Msg](windowSize)
# we need to warmup Nim's memory allocator so that not most
# of the time is spent in mmap()... Hopefully later versions of Nim
# will be smarter and allocate larger pieces from the OS:
for i in 0 .. <msgCount:
pushMsg0(b, i)
# now after warmup, we can measure things:
for i in 0 .. <msgCount:
pushMsg1(b, i)
echo("Worst push time: ", worst, " nano seconds")
echo(GC_getStatistics())
when isMainModule:
main()
```
On my slower machine, I get latencies of max 0.3ms.