Browse Source

Inline Array.map/filter methods (#5749)

* [js] inline Array.map when possible

* [js] inline Array.filter too

* inline map/filter by default

* [cpp] optimize Array.map

* [cs] inline (also optimize a bit) Array.map/filter

* [java] inline Array.map/filter (use slower `__get/__set` for now, since unsafe versions fail, issue incoming)

* [lua] inline Array.map/filter

* [neko] inline Array.map/filter

* use the new NativeArray.create function

* Merge development into array_map_inline

* fix cppia

* [php] minor Array refactoring
Dan Korostelev 6 years ago
parent
commit
6a44de17c4
7 changed files with 49 additions and 32 deletions
  1. 12 2
      std/Array.hx
  2. 8 6
      std/cs/_std/Array.hx
  3. 8 6
      std/java/_std/Array.hx
  4. 7 2
      std/js/_std/Array.hx
  5. 2 2
      std/lua/_std/Array.hx
  6. 7 5
      std/neko/_std/Array.hx
  7. 5 9
      std/php/_std/Array.hx

+ 12 - 2
std/Array.hx

@@ -274,7 +274,15 @@ extern class Array<T> {
 
 		If `f` is null, the result is unspecified.
 	**/
-	function map<S>(f:T->S):Array<S>;
+	@:runtime inline function map<S>(f:T->S):Array<S> {
+		#if (cpp && !cppia)
+		var result = cpp.NativeArray.create(length);
+		for (i in 0...length) cpp.NativeArray.unsafeSet(result, i, f(cpp.NativeArray.unsafeGet(this, i)));
+		return result;
+		#else
+		return [for (v in this) f(v)];
+		#end
+	}
 
 	/**
 		Returns an Array containing those elements of `this` for which `f`
@@ -284,7 +292,9 @@ extern class Array<T> {
 
 		If `f` is null, the result is unspecified.
 	**/
-	function filter(f:T->Bool):Array<T>;
+	@:runtime inline function filter(f:T->Bool):Array<T> {
+		return [for (v in this) if (f(v)) v];
+	}
 
 	/**
 		Set the length of the Array.

+ 8 - 6
std/cs/_std/Array.hx

@@ -390,18 +390,20 @@ final class Array<T> implements ArrayAccess<T> {
 		return false;
 	}
 
-	public function map<S>(f:T->S):Array<S> {
-		var ret = [];
-		for (elt in this)
-			ret.push(f(elt));
+	public inline function map<S>(f:T->S):Array<S> {
+		var ret = alloc(length);
+		for (i in 0...length)
+			ret.__unsafe_set(i, f(__unsafe_get(i)));
 		return ret;
 	}
 
-	public function filter(f:T->Bool):Array<T> {
+	public inline function filter(f:T->Bool):Array<T> {
 		var ret = [];
-		for (elt in this)
+		for (i in 0...length) {
+			var elt = __unsafe_get(i);
 			if (f(elt))
 				ret.push(elt);
+		}
 		return ret;
 	}
 

+ 8 - 6
std/java/_std/Array.hx

@@ -432,18 +432,20 @@ import java.NativeArray;
 		}
 	}
 
-	public function map<S>(f:T->S):Array<S> {
-		var ret = [];
-		for (elt in this)
-			ret.push(f(elt));
+	public inline function map<S>(f:T->S):Array<S> {
+		var ret = alloc(length);
+		for (i in 0...length)
+			ret.__set(i, f(__get(i)));
 		return ret;
 	}
 
-	public function filter(f:T->Bool):Array<T> {
+	public inline function filter(f:T->Bool):Array<T> {
 		var ret = [];
-		for (elt in this)
+		for (i in 0...length) {
+			var elt = __get(i);
 			if (f(elt))
 				ret.push(elt);
+		}
 		return ret;
 	}
 

+ 7 - 2
std/js/_std/Array.hx

@@ -62,8 +62,13 @@ extern class Array<T> {
 		return (cast this).slice();
 	}
 
-	function map<S>(f:T->S):Array<S>;
-	function filter(f:T->Bool):Array<T>;
+	@:runtime inline function map<S>(f:T->S):Array<S> {
+		return [for (v in this) f(v)];
+	}
+
+	@:runtime inline function filter(f:T->Bool):Array<T> {
+		return [for (v in this) if (f(v)) v];
+	}
 
 	@:runtime inline function iterator():Iterator<T> {
 		return @:privateAccess HxOverrides.iter(this);

+ 2 - 2
std/lua/_std/Array.hx

@@ -227,11 +227,11 @@ class Array<T> {
 		return [for (i in this) i];
 	}
 
-	public function map<S>(f:T->S):Array<S> {
+	public inline function map<S>(f:T->S):Array<S> {
 		return [for (i in this) f(i)];
 	}
 
-	public function filter(f:T->Bool):Array<T> {
+	public inline function filter(f:T->Bool):Array<T> {
 		return [for (i in this) if (f(i)) i];
 	}
 

+ 7 - 5
std/neko/_std/Array.hx

@@ -286,14 +286,16 @@
 		return ret;
 	}
 
-	public function map<S>(f:T->S):Array<S> {
-		var ret = [];
-		for (elt in this)
-			ret.push(f(elt));
+	public inline function map<S>(f:T->S):Array<S> {
+		var l = length;
+		var ret = new1(neko.NativeArray.alloc(l), l);
+		for (i in 0...l) {
+			ret[i] = f(this[i]);
+		}
 		return ret;
 	}
 
-	public function filter(f:T->Bool):Array<T> {
+	public inline function filter( f : T -> Bool ) : Array<T> {
 		var ret = [];
 		for (elt in this)
 			if (f(elt))

+ 5 - 9
std/php/_std/Array.hx

@@ -45,12 +45,10 @@ final class Array<T> implements ArrayAccess<Int, T> {
 
 	public inline function filter(f:T->Bool):Array<T> {
 		var result = Syntax.arrayDecl();
-		var i = 0;
-		while (i < length) {
-			if (f(arr[i])) {
-				result.push(arr[i]);
+		for(item in arr) {
+			if (f(item)) {
+				result.push(item);
 			}
-			i++;
 		}
 		return wrap(result);
 	}
@@ -109,10 +107,8 @@ final class Array<T> implements ArrayAccess<Int, T> {
 
 	public inline function map<S>(f:T->S):Array<S> {
 		var result = Syntax.arrayDecl();
-		var i = 0;
-		while (i < length) {
-			result.push(f(arr[i]));
-			i++;
+		for(item in arr) {
+			result.push(f(item));
 		}
 		return wrap(result);
 	}