Update 3: I make a script to automate the benchmarking to some degree, using 
hyperfine
    
    
    .nim
    import std/[osproc,os],strformat,strutils,times,algorithm
    let starttime = cpuTime()
    type paramOpt = tuple[name,cmd: string]
    let allparameters:seq[paramOpt]= 
@[("danger","-d:danger"),("clang","--cc:clang"),("mas","--mm:markandsweep"),("threadsoff","--threads:off")]
    var possibleCombos = newSeq[paramOpt]()
    proc getpossibleCombos =
      var base:paramOpt
      let allparameterslen = allparameters.len
      var basepoint,afterbase,length:int
      proc appendTuple(b:seq[paramOpt]): paramOpt=
        var a:paramOpt
        for x in b:
          a.name.add(x.name & " ")
          a.cmd.add(x.cmd & " ")
        return a
      while length < allparameterslen-2:
        afterbase = basepoint+length
        while basepoint<allparameterslen-length:
          for thisoption in allparameters[afterbase..<allparameterslen]: 
possibleCombos.add((base.name & thisoption.name,base.cmd & thisoption.cmd))
          base = appendTuple(allparameters[basepoint..basepoint+length])
          inc afterbase
          inc basepoint
        basepoint = 0
        inc length
        base = appendTuple(allparameters[basepoint..basepoint+length])
        inc basepoint
      var lastitem:paramOpt
      lastitem = appendTuple(allparameters)
      possibleCombos.add lastitem
    getpossibleCombos()
    
    proc findmean(output: string): (float,string)=
    # proc findmean(output: string): string=
      var lines = output.splitLines(false)
      for line in lines:
        if line.contains("mean"):
          var tmp1 = line.split(":")[1]
          var tmp2 = tmp1.splitWhitespace()
          var tmp3 = tmp2[1..4].join " "
          # return tmp2.join " "
          return (tmp2[0].parseFloat,tmp3)
    
    proc sysexec(command: string): tuple=
      var res = execCmdEx(command)
      if res.exitCode != 0:
        echo 1, " " & command
        echo res.output
        system.quit(1)
      return res
    
    # type result= tuple[time,name: string]
    type result= tuple[time:(float,string),name: string]
    var benchSlice: seq[result]
    var benchdir = "bench" & format(times.now(),"yyyyMMdd-HHmm")
    os.createDir(benchdir)
    var sourcenim = os.paramStr(1)
    var res = sysexec(fmt"nim --hints:off c -r --o:{benchdir}\base.exe 
{sourcenim}")
    echo "base:  ",res.output
    # var baseoutput = res.output
    res = sysexec(fmt"hyperfine {benchdir}\base.exe")
    benchSlice.add((res.output.findmean,"base.exe"))
    # var params:string
    # var warmup = if (os.paramCount() == 2): os.paramStr(2) else: 10.intToStr
    for lang in ["c","cpp"]:
      for param in possibleCombos:
        var targetexe = "\"" & benchdir & "\\" & param.name & ".exe\""
        res = sysexec(&"nim {lang} --hints:off -r {param.cmd} --o:{targetexe} 
{sourcenim}")
        echo param.cmd,":  ",res.output
        #   system.quit(1)
        res = sysexec(fmt"hyperfine -i --show-output {targetexe}")
        # var res = sysexec(fmt"hyperfine {targetexe} --warmup {warmup}")
        benchSlice.add((res.output.findmean,lang & " " & param.name))
    benchSlice.sort(proc (a,b:result):int = cmp(a.time[0],b.time[0]))
    let benchmarkfile = benchdir & "\\" & "benchmark.txt"
    try: os.removeFile(benchmarkfile)
    except: discard
    var benchstr = benchSlice.join("\n")
    echo benchstr
    echo "Benchmarked ", possibleCombos.len * 2 + 1, " programs in ", cpuTime() 
- starttime, "s"
    writeFile(benchmarkfile,benchstr)
    
    
    Run

Fibonacci 50 fares as follows:
    
    
    (time: (92.3, "92.3 ms ± 4.2 ms"), name: "c danger clang mas")
    (time: (101.0, "101.0 ms ± 7.2 ms"), name: "c danger clang mas threadsoff ")
    (time: (105.9, "105.9 ms ± 11.3 ms"), name: "cpp danger clang mas")
    (time: (107.9, "107.9 ms ± 7.4 ms"), name: "c clang mas")
    (time: (109.6, "109.6 ms ± 9.6 ms"), name: "c clang mas threadsoff")
    (time: (118.8, "118.8 ms ± 9.7 ms"), name: "cpp clang mas")
    (time: (122.4, "122.4 ms ± 8.2 ms"), name: "cpp clang mas threadsoff")
    (time: (123.9, "123.9 ms ± 10.1 ms"), name: "cpp danger clang mas 
threadsoff ")
    (time: (135.9, "135.9 ms ± 9.3 ms"), name: "c danger mas")
    (time: (146.4, "146.4 ms ± 5.6 ms"), name: "cpp danger mas")
    (time: (172.0, "172.0 ms ± 5.9 ms"), name: "c danger clang threadsoff")
    (time: (173.5, "173.5 ms ± 6.9 ms"), name: "c danger threadsoff")
    (time: (175.3, "175.3 ms ± 10.4 ms"), name: "c mas")
    (time: (176.7, "176.7 ms ± 6.1 ms"), name: "cpp danger threadsoff")
    (time: (178.9, "178.9 ms ± 11.4 ms"), name: "cpp danger clang threadsoff")
    (time: (179.3, "179.3 ms ± 6.5 ms"), name: "cpp danger clang")
    (time: (179.4, "179.4 ms ± 5.2 ms"), name: "c danger clang")
    (time: (180.8, "180.8 ms ± 3.0 ms"), name: "c mas threadsoff")
    (time: (181.5, "181.5 ms ± 4.6 ms"), name: "cpp danger")
    (time: (181.6, "181.6 ms ± 7.4 ms"), name: "c danger")
    (time: (184.8, "184.8 ms ± 6.2 ms"), name: "c clang threadsoff")
    (time: (188.8, "188.8 ms ± 8.2 ms"), name: "c threadsoff")
    (time: (188.9, "188.9 ms ± 10.7 ms"), name: "cpp clang threadsoff")
    (time: (189.9, "189.9 ms ± 12.3 ms"), name: "cpp mas")
    (time: (191.3, "191.3 ms ± 7.8 ms"), name: "cpp mas threadsoff")
    (time: (191.4, "191.4 ms ± 5.6 ms"), name: "c clang")
    (time: (194.6, "194.6 ms ± 5.5 ms"), name: "cpp clang")
    (time: (209.6, "209.6 ms ± 3.0 ms"), name: "cpp threadsoff")
    (time: (327.6, "327.6 ms ± 6.5 ms"), name: "base.exe")
    
    
    Run

where mas is markandsweep

Reply via email to