Optimization, my favorite Nim topic!

Runtime of your version for me: 0.766 s
    
    
    res.add board[d[i]]
    

This line resizes the `res` seq, instead you should allocate it to have the 
correct size directly. Like this: 
    
    
    proc do_something(board: seq[char]): seq[char] =
       var res = newSeq[char](board.len * Directions.len)
       for i, p in board:
          for j, d in Directions:
             res[i * Directions.len + j] = board[d[i]]
       return res
    

New runtime: 0.073 s

With the new devel branch of Nim you can also use `newSeqOfCap` if you don't 
want to manually calculate the index:
    
    
    proc do_something(board: seq[char]): seq[char] =
       var res = newSeqOfCap[char](board.len * Directions.len)
       for i, p in board:
          for d in Directions:
             res.add board[d[i]]
       return res
    

As a workaround you can also do `var res = newSeq[char](board.len * 
Directions.len); res.setLen(0)` to achieve the same effect.
    
    
    res = do_something(board)
    

You create a new `res` seq for every call to do_something. Instead you could 
reuse a single data structure and pass it to `do_something`. But that's 
probably not what you want to benchmark then.

Full code with some cleanup (use implicit result variable, no `$` for echo, 
arrays instead of seqs, more consts):
    
    
    # Nim example to test execution speed against a Python version
    import times, os
    
    const
      board = ['0', 'p', '.', 'p', 'P', '.', 'p', 'P', '.', 'p', '.', 'p', 'P', 
'.', 'p']
      NE = [8, 2, 13, 4, 5, 7, 8, 3, 9, 12, 7, 8, 3, 9, 12]
      Directions = [NE, NE, NE, NE]  # for short: in real application the array 
elements differ
    
    proc do_something(board: openarray[char]): seq[char] =
      result = newSeqOfCap[char](board.len * Directions.len)
      for i in 0 .. board.high:
        for d in Directions:
          result.add board[d[i]]
    
    let t0 = cpuTime()
    var res: seq[char]
    const count = 100_000
    for i in 1..count:
      res = do_something(board)
    let t1 =  cpuTime()
    echo "***** Time elapsed for Nim: ", t1 - t0, "  Counts: ", count
    echo res.repr
    

New runtime: 0.065 s

For comparison, Python runtime: 0.783 s

Reply via email to