Revision: 4683
Author:   [email protected]
Date:     Wed Dec 14 15:06:47 2011
Log:      faster es53 freeze
http://codereview.appspot.com/5484074

This change reduces runtime of a minimal test gadget
from 2800ms to 1800ms in Chrome Beta (16.0),

Basically, much of the cost of es53+domado startup is freeze,
and much of the cost of freeze is iterating over object properties,
which includes inherited properties which have to be ignored.

This change tries to use a native Object.keys function to do
a fast initial filtering of the properties.

[email protected]

http://code.google.com/p/google-caja/source/detail?r=4683

Modified:
 /trunk/src/com/google/caja/es53.js

=======================================
--- /trunk/src/com/google/caja/es53.js  Tue Nov  8 10:55:13 2011
+++ /trunk/src/com/google/caja/es53.js  Wed Dec 14 15:06:47 2011
@@ -220,6 +220,17 @@
       }
     };
   }
+
+  var hasOwnProperty = Object.prototype.hasOwnProperty;
+  var fastOwnKeys = Object.keys || function fastOwnKeys(o) {
+    // In IE<9, this will miss some keys, like an own 'toString', but that
+ // doesn't matter, because we're only using this to find ___ properties.
+    var keys = [];
+    for (var k in o) {
+      if (hasOwnProperty.call(o, k)) { keys.push(k); }
+    }
+    return keys;
+  };

   Object.prototype.freeze___ = function() {
       // Frozen means all the properties are neither writable nor
@@ -233,17 +244,16 @@
       if (this.v___ === deferredV) {
         this.v___('length');
       }
-      for (var i in this) {
-        if (!this.hasOwnProperty(i)) { continue; }
-        if (isNumericName(i)) { continue; }
-        var m = i.match(endsWith_v___);
-        if (!m) { continue; }
-        var P = m[1];
+      var keys = fastOwnKeys(this);
+      for (var k = 0, n = keys.length; k < n; k++) {
+        var i = keys[k];
+        if (i.substr(-5) !== '_v___' || i.length < 6) { continue; }
+        var P = i.substr(0, i.length - 5);
         this[P + '_c___'] = false;
         this[P + '_gw___'] = false;
         this[P + '_w___'] = false;
       }
-      if (!this.hasNumerics___()) {
+      if (!this.NUM____v___ === this) { // inline this.hasNumerics___()
         this.NUM____v___ = this;
         this.NUM____e___ = this;
         this.NUM____g___ = void 0;

Reply via email to