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>

lib/standard/collection/array.nit
tests/sav/test_new_native_alt1.res

index 253dd9e..233621e 100644 (file)
@@ -130,7 +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 @@ 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]
index cf299e7..1fb7aeb 100644 (file)
@@ -1,4 +1,4 @@
-Runtime error: Cast failed. Expected `E`, got `Bool` (../lib/standard/collection/array.nit:894)
+Runtime error: Cast failed. Expected `E`, got `Bool` (../lib/standard/collection/array.nit:909)
 NativeString
 N
 Nit