Author: [EMAIL PROTECTED]
Date: Mon Sep 15 15:12:59 2008
New Revision: 3651

Modified:
     
trunk/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Array.java

Log:
Two tweaks to improve Array instantiation performance.

1) For reference-type arrays, we no longer need to initialize to 'null'  
explicitly since 'undefined' works just as well.

2) Instead of caching a protoTypeArray and using for-in to copy expandos,  
cache the names and values in a pair of arrays.  Array iteration is  
generally faster than for-in.  This also uses  
the "static-initializer-inner-class" pattern to avoid lazy checks and also  
factor the code out.

Review by: bobv

Modified:  
trunk/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Array.java
==============================================================================
---  
trunk/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Array.java
     
(original)
+++  
trunk/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Array.java
     
Mon Sep 15 15:12:59 2008
@@ -21,6 +21,55 @@
   */
  public final class Array {

+  private static final class ExpandoWrapper {
+    /**
+     * A JS array containing the names of any expandos we need to add to  
arrays
+     * (such as "hashCode", "equals", "toString").
+     */
+    private static final Object expandoNames = makeEmptyJsArray();
+
+    /**
+     * A JS array containing the values of any expandos we need to add to  
arrays
+     * (such as hashCode(), equals(), toString()).
+     */
+    private static final Object expandoValues = makeEmptyJsArray();
+
+    static {
+      initExpandos(new Array(), expandoNames, expandoValues);
+    }
+
+    public static void wrapArray(Array array) {
+      wrapArray(array, expandoNames, expandoValues);
+    }
+
+    private static native void initExpandos(Array protoType,
+        Object expandoNames, Object expandoValues) /*-{
+      var i = 0, value;
+      for (var name in protoType) {
+        // Only copy non-null values over; this generally means only  
functions
+        // will get copied over, and not fields, which is good because we  
will
+        // setup the fields manually and it's best if length doesn't get  
blown
+        // away.
+        if (value = protoType[name]) {
+          expandoNames[i] = name;
+          expandoValues[i] = value;
+          ++i;
+        }
+      }
+    }-*/;
+
+    private static native Object makeEmptyJsArray() /*-{
+      return [];
+    }-*/;
+
+    private static native void wrapArray(Array array, Object expandoNames,
+        Object expandoValues) /*-{
+      for (var i = 0, c = expandoNames.length; i < c; ++i) {
+        array[expandoNames[i]] = expandoValues[i];
+      }
+    }-*/;
+  }
+
    /*
     * TODO: static init instead of lazy init when we can elide the clinit  
calls.
     */
@@ -34,12 +83,6 @@
    static final int ZERO_SEED_TYPE = 1;

    /**
-   * Stores the prototype Array so that arrays can get their polymorphic  
methods
-   * via expando.
-   */
-  private static Array protoTypeArray;
-
-  /**
     * Creates a copy of the specified array.
     */
    public static <T> T[] clone(T[] array) {
@@ -123,10 +166,7 @@
     */
    public static Array initValues(Class arrayClass, int typeId, int queryId,
        Array array) {
-    if (protoTypeArray == null) {
-      protoTypeArray = new Array();
-    }
-    wrapArray(array, protoTypeArray);
+    ExpandoWrapper.wrapArray(array);
      array.arrayClass = arrayClass;
      Util.setTypeId(array, typeId);
      array.queryId = queryId;
@@ -151,7 +191,7 @@
    private static native Array arraySlice(Array array, int fromIndex, int  
toIndex) /*-{
      return array.slice(fromIndex, toIndex);
    }-*/;
-
+
    /**
     * Use JSNI to effect a castless type change.
     */
@@ -177,11 +217,12 @@
     * @return the new JSON array
     */
    private static native Array createFromSeed(int seedType, int length) /*-{
-    var seedArray = [null, 0, false, [0, 0]];
-    var value = seedArray[seedType];
      var array = new Array(length);
-    for (var i = 0; i < length; ++i) {
-      array[i] = value;
+    if (seedType > 0) {
+      var value = [null, 0, false, [0, 0]][seedType];
+      for (var i = 0; i < length; ++i) {
+        array[i] = value;
+      }
      }
      return array;
    }-*/;
@@ -212,23 +253,9 @@
      return array[index] = value;
    }-*/;

-  private static native Array wrapArray(Array array, Array protoTypeArray)  
/*-{
-    for (var i in protoTypeArray) {
-      // Only copy non-null values over; this generally means only  
functions
-      // will get copied over, and not fields, which is fine because we  
will
-      // setup the fields manually and it's best if length doesn't get  
blown
-      // away.
-      var toCopy = protoTypeArray[i];
-      if (toCopy) {
-        array[i] = toCopy;
-      }
-    }
-    return array;
-  }-*/;
-
    /*
     * Explicitly initialize all fields to JS false values; see comment in
-   * wrapArray(Array, Array).
+   * ExpandoWrapper.initExpandos().
     */
    public volatile int length = 0;
    protected Class arrayClass = null;

--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---

Reply via email to