I typed up my answer. I was ready to post. I hit preview, and... Araq beat me 
by a few minutes!  Oh well, maybe this post would still have some value...

* * *

I get similar results: the perl program is about three times faster. 

OK, let's `use Time::HiRes`, `import times` 
[(etc)](https://gist.github.com/lbmn/d424dd0c8c85fa195743356fc133235a) for some 
ad-hoc time-subtracting.

About 24.5% of the Nim program's execution time is spent on 
`surface.write_to_png image`, which is actually a bit faster than Perl, so the 
cairo bindings are not the problem.

About 75% of the Nim program's execution time is spent on `draw(level, t1)`. 
That proc uses recurses multiple times (level 12 to 3), but it uses about 69% 
of the total program time when level is 4, in which case the loop is executed 
6561 times. So let's zoom in on this loop...

**Wowzers, 88% of the time in that inner loop is spent just on concatenating 
seqs! So that is our problem...**

I don't know what the best solution is, but one [step in the right 
direction](https://gist.github.com/lbmn/32f20a60e8cc4b5157c9a94fa3adcafc) would 
be to allocate next before the for loop in draw():
    
    
    var next: trias = newSeq[trian]()

And to use add inside the loop:
    
    
    next.add @[
      (HEAD, left, right),
      (left, LEFT, tail),
      (right, tail, RIGHT)
    ]
    

And now we're 18% faster than perl. 

Reply via email to