@jlp765 : yeah probably, and stefan said that, but I find this interesting :)

So, based on [this 
thread](http://forum.nim-lang.org///forum.nim-lang.org/t/1471/2) , using reset 
on the elements we move out of the array should handle ref etc. properly.

The code becomes this: 
    
    
    proc shift[T](a: var openarray[T]; d: int) =
      if d == 0: discard # do nothing
      elif abs(d) >= a.len: # reset all
        for el in a.mitems: el.reset
      elif d > 0: # right shift
        moveMem(addr a[d], addr a[0], (a.len - d)*sizeof(T))
        for j in 0..<d: a[j].reset # Reset only items that were not moved
      elif d < 0: # left shift
        moveMem(addr a[0], addr a[-d], (a.len + d)*sizeof(T))
        for j in countdown(-d,1): a[^j].reset # Reset only items that were not 
moved
    

And running [a naive 
benchmark](https://gist.github.com/stisa/3b32af4e2a1306c5f9a3c55731d6a6dd) on a 
win10 notebook with a quadcore i7 I get:
    
    
    CPU time: original 4.11s
    Delta occupied mem: original -483328
    CPU time: first stisa 4.736s
    Delta occupied mem: first stisa -479232
    CPU time: possibly leaking 0.04800000000000004s
    Delta occupied mem: possibly leaking -475136
    CPU time: last stisa 2.263999999999999s
    Delta occupied mem: last stisa -479232
    

Note that `last stisa` gets closer to `possibly leaking` the closer to the 
edges we shift, while `original` and `first stisa` gets slower:

shift(1): 
    
    
    CPU time: original 23.209s
    Delta occupied mem: original -483328
    CPU time: first stisa 23.261s
    Delta occupied mem: first stisa -479232
    CPU time: possibly leaking 0.03400000000000603s
    Delta occupied mem: possibly leaking -475136
    CPU time: last stisa 0.04699999999999704s
    Delta occupied mem: last stisa -479232
    

shift(5000): 
    
    
    CPU time: original 3.831s
    Delta occupied mem: original -430080
    CPU time: first stisa 4.416s
    Delta occupied mem: first stisa -479232
    CPU time: possibly leaking 0.04899999999999949s
    Delta occupied mem: possibly leaking -475136
    CPU time: last stisa 2.227s
    Delta occupied mem: last stisa -479232
    

I don't understand the gc enough to draw any conclusions,and it may very well 
be that what I wrote is flawed in ways I can't see, but the `possibly_leaking` 
seems to consistently free less memory than others.

ps: compiling with `-d:release` brings down times considerably, eg shift(1) 
:`original` 2.5s ( `last_stisa` 0.035s) and shift(5000):`original` 0.8s ( 
`last_stisa` 0.38s)

pps: is there a way to know how many times something is referenced? ( so I can 
tell how many calls to GC_unref() would be needed to cause the gc to collect it 
) 

Reply via email to