Merge: Reuse Array Iterators
authorJean Privat <jean@pryen.org>
Sat, 7 Mar 2015 05:17:28 +0000 (12:17 +0700)
committerJean Privat <jean@pryen.org>
Sat, 7 Mar 2015 05:17:28 +0000 (12:17 +0700)
on nitc/nitc/nit this reduce a lot the number of allocated iterators.

before:

* 0m7.168s
* 2,706,498 new ArrayIterator
* the second most allocated class (after NativeArray)

after:

* 0m7.060s (-1.5%)
* 785,781 new ArrayIterator (-70%)
* the 7th most allocated class

Pull-Request: #1190
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>

1  2 
lib/standard/collection/array.nit

@@@ -130,7 -130,20 +130,20 @@@ abstract class AbstractArrayRead[E
                end
        end
  
-       redef fun iterator: ArrayIterator[E] do return new ArrayIterator[E](self)
+       redef fun iterator: ArrayIterator[E] do
+               var res = _free_iterator
+               if res == null then return new ArrayIterator[E](self)
+               res._index = 0
+               _free_iterator = null
+               return res
+       end
+       # An old iterator, free to reuse.
+       # Once an iterator is `finish`, it become reusable.
+       # Since some arrays are iterated a lot, this avoid most of the
+       # continuous allocation/garbage-collection of the needed iterators.
+       private var free_iterator: nullable ArrayIterator[E] = null
        redef fun reverse_iterator do return new ArrayReverseIterator[E](self)
  end
  
@@@ -477,6 -490,8 +490,8 @@@ private class ArrayIterator[E
        redef var index = 0
  
        var array: AbstractArrayRead[E]
+       redef fun finish do _array._free_iterator = self
  end
  
  private class ArrayReverseIterator[E]
@@@ -618,8 -633,8 +633,8 @@@ class ArrayMap[K, E
                end
        end
  
 -      redef var keys: RemovableCollection[K] = new ArrayMapKeys[K, E](self)
 -      redef var values: RemovableCollection[E] = new ArrayMapValues[K, E](self)
 +      redef var keys: RemovableCollection[K] = new ArrayMapKeys[K, E](self) is lazy
 +      redef var values: RemovableCollection[E] = new ArrayMapValues[K, E](self) is lazy
  
        # O(1)
        redef fun length do return _items.length