Ver código fonte

[cs] move intmap key iterator into a class instead of dynamic object with closures (~2.3x faster)

Dan Korostelev 11 anos atrás
pai
commit
8dc7eecafb
1 arquivos alterados com 39 adições e 29 exclusões
  1. 39 29
      std/cs/_std/haxe/ds/IntMap.hx

+ 39 - 29
std/cs/_std/haxe/ds/IntMap.hx

@@ -326,31 +326,9 @@ import cs.NativeArray;
 		Returns an iterator of all keys in the hashtable.
 		Implementation detail: Do not set() any new value while iterating, as it may cause a resize, which will break iteration
 	**/
-	public function keys() : Iterator<Int>
+	public inline function keys() : Iterator<Int>
 	{
-		var i = 0;
-		var len = nBuckets;
-		return {
-			hasNext: function() {
-				for (j in i...len)
-				{
-					if (!isEither(flags, j))
-					{
-						i = j;
-						return true;
-					}
-				}
-				return false;
-			},
-			next: function() {
-				var ret = _keys[i];
-				cachedIndex = i;
-				cachedKey = ret;
-
-				i = i + 1;
-				return ret;
-			}
-		};
+		return new IntMapKeyIterator(this);
 	}
 
 	/**
@@ -435,6 +413,38 @@ import cs.NativeArray;
 		return ((m) < 16? 1 : (m) >> 4);
 }
 
+@:access(haxe.ds.IntMap)
+@:final
+private class IntMapKeyIterator<T> {
+	var m:IntMap<T>;
+	var i:Int;
+	var len:Int;
+
+	public function new(m:IntMap<T>) {
+		this.i = 0;
+		this.m = m;
+		this.len = m.nBuckets;
+	}
+
+	public function hasNext():Bool {
+		for (j in i...len) {
+			if (!IntMap.isEither(m.flags, j)) {
+				i = j;
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public function next():Int {
+		var ret = m._keys[i];
+		m.cachedIndex = i;
+		m.cachedKey = ret;
+		i++;
+		return ret;
+	}
+}
+
 @:access(haxe.ds.IntMap)
 @:final
 private class IntMapValueIterator<T> {
@@ -443,12 +453,12 @@ private class IntMapValueIterator<T> {
 	var len:Int;
 
 	public function new(m:IntMap<T>) {
-		untyped this.i = 0;
-		untyped this.m = m;
-		untyped this.len = m.nBuckets;
+		this.i = 0;
+		this.m = m;
+		this.len = m.nBuckets;
 	}
 
-	public function hasNext() {
+	public function hasNext():Bool {
 		for (j in i...len) {
 			if (!IntMap.isEither(m.flags, j)) {
 				i = j;
@@ -458,7 +468,7 @@ private class IntMapValueIterator<T> {
 		return false;
 	}
 
-	public inline function next() {
+	public inline function next():T {
 		return m.vals[i++];
 	}
 }