Hello! I was following a tutorial on Bayesian inference and tried to implement 
the example given in nim. During that I found out that the first execution 
after compilation takes a lot longer than the following executions. Can someone 
explain me why?

Here are the timing result:

And here is the code i used:
    
    
    import random, sequtils,future, times, os, strutils
    
    template benchmark(benchmarkName: string, code: untyped) =
      let t0 = epochTime()
      code
      let elapsed = epochTime() - t0
      let elapsedStr = elapsed.formatFloat(format = ffDecimal, precision = 5)
      echo "CPU Time [", benchmarkName, "] ", elapsedStr, "s"
    
    benchmark "Total":
      
      
      proc sampler(param:float): auto =
        iterator sample (): float {.closure.} =
          while true:
            if rand(1.0) < param:
              yield 1.0
            else:
              yield 0.0
        
        return sample
      
      proc take[T](iter: iterator():T,n:int): seq[T] =
        result = newSeq[T](n)
        
        for i in 0..<n:
          result[i] = iter()
      
      
      proc genModel(param: float):float =
        
        result = 0.0
        for e in sampler(param).take(16):
          result += e
        
        result = result/16.0
      
      proc samplePrior():float =
        rand(1.0)
      
      proc bin[T](xs,ys:openArray[T],nBins:int,associatedX: float = 0.0): auto =
        result = newSeq[tuple[x:T,count:int]](0)
        let
          leftBound = min(xs)
          rightBound = max(xs)
          dx = (rightBound-leftBound)/nBins.toFloat
        
        for i in 1..<nBins:
          let j = i.toFloat
          result.add (leftBound + (j+associatedX)*dx,len(filter(xs, x => 
(leftBound + j*dx)<= x and x < (leftBound + (j+1)*dx))))
      
      
      const data = 6/16
      
      const nSamples = 100_000
      var sampling: array[nSamples,tuple[param:float,result:float]]
      benchmark "Sampeling":
        for i in 0..<nSamples:
          let tmp = samplePrior()
          sampling[i] = (tmp, genModel(tmp))
      
      
      benchmark "Filtering":
        let filteredData = filter(sampling, t => t.result == data)
      
      benchmark "Binning":
        let  binnedData = bin(map(filteredData, t => t.param), 
map(filteredData, t => t.result), 20)
      
      benchmark "Totaling":
        let total = foldl(map(binnedData, t => t.count), a+b)
      
      benchmark "Posterior":
        let posterior = map(binnedData, t => (x: t.x, prob: t.count/total))
    
    
    
    
    Run

Reply via email to