enyojs/enyo — pull request #407 by clinuz (2013-08-26 18:25:57+00:00)
Title: Rewrite enyo.getPath and enyo.setPath for better performance

The only notable change in API here is that `enyo.setPath` no longer accepts a _comparator_ method as the optional third parameter.

# Simple path with native objects

```
var b = TARGET = {};
SEARCH_STRING = "";
for (var i=0; i<100; ++i) {
b = b[i] = {};
SEARCH_STRING += ("." + i);
}
b.target = "complete";
SEARCH_STRING += ("." + "target");

var d = enyo.dev.bench({name: "getPath", average: true, autoStart: false, logging: false});
for (i=0; i<1000; ++i) {
d.start();
enyo.getPath.call(TARGET, SEARCH_STRING);
d.stop();
}
enyo.dev.report("getPath");
```

#### New getPath

```
- - - - - - - - - - - - - - - - -
BENCHMARK REPORT (averages): getPath
TOTAL TIME (ms): 19.422999990638345
AVERAGE TIME (ms): 0.019422999990638345
MINIMUM TIME (ms): 0.012999997125007212
MAXIMUM TIME (ms): 1.339999998890562
NUMBER OF ENTRIES: 1000
- - - - - - - - - - - - - - - - -
```

#### Old getPath

```
- - - - - - - - - - - - - - - - -
BENCHMARK REPORT (averages): getPath
TOTAL TIME (ms): 138.07400007499382
AVERAGE TIME (ms): 0.13807400007499382
MINIMUM TIME (ms): 0.12000000060652383
MAXIMUM TIME (ms): 0.9610000015527476
NUMBER OF ENTRIES: 1000
- - - - - - - - - - - - - - - - -
```

# Simple path using enyo.Objects

```
var b = TARGET = {};
SEARCH_STRING = "";
for (var i=0; i<100; ++i) {
b = b[i] = new enyo.Object();
SEARCH_STRING += ("." + i);
}
b.target = "complete";
SEARCH_STRING += ("." + "target");

var d = enyo.dev.bench({name: "getPath", average: true, autoStart: false, logging: false});
for (i=0; i<1000; ++i) {
d.start();
enyo.getPath.call(TARGET, SEARCH_STRING);
d.stop();
}
enyo.dev.report("getPath");
```

#### New getPath

```
- - - - - - - - - - - - - - - - -
BENCHMARK REPORT (averages): getPath
TOTAL TIME (ms): 22.109999983513262
AVERAGE TIME (ms): 0.022109999983513262
MINIMUM TIME (ms): 0.015000001440057531
MAXIMUM TIME (ms): 1.410999997460749
NUMBER OF ENTRIES: 1000
- - - - - - - - - - - - - - - - -
```

#### Old getPath

```
- - - - - - - - - - - - - - - - -
BENCHMARK REPORT (averages): getPath
TOTAL TIME (ms): 142.18500003698864
AVERAGE TIME (ms): 0.14218500003698864
MINIMUM TIME (ms): 0.1230000016221311
MAXIMUM TIME (ms): 1.1689999992086086
NUMBER OF ENTRIES: 1000
- - - - - - - - - - - - - - - - -
```

# Heavy path computed properties and enyo.Component without caching

```
TARGET = null;
SEARCH_STRING = "";

enyo.kind({
name: "TARGET_KIND",
kind: enyo.Component,
generateRelationship: function () {
var c = new TARGET_KIND({owner: this});
c.name = null;
c.id = c.makeId();
this.computed[c.id] = [];
this[c.id] = function () {
return c;
}
SEARCH_STRING += ("." + c.id);
return c;
}
});
var b = TARGET = new TARGET_KIND();
for (var i=0; i<10; ++i) {
b = b.generateRelationship();
}
b.target = "complete";
SEARCH_STRING += ("." + "target");
var d = enyo.dev.bench({name: "getPath", average: true, autoStart: false, logging: false});
for (i=0; i<1000; ++i) {
d.start();
enyo.getPath.call(TARGET, SEARCH_STRING);
d.stop();
}
enyo.dev.report("getPath");
```

#### New getPath

```
- - - - - - - - - - - - - - - - -
BENCHMARK REPORT (averages): getPath
TOTAL TIME (ms): 144.60300008795457
AVERAGE TIME (ms): 0.14460300008795457
MINIMUM TIME (ms): 0.1320000010309741
MAXIMUM TIME (ms): 1.3639999997394625
NUMBER OF ENTRIES: 1000
- - - - - - - - - - - - - - - - -
```

#### Old getPath

```
N/A CANNOT COMPLETE TASK - INCAPABLE OF TRACING COMPUTED PROPERTIES IN PATH
```

# Repeatedly rebuilding a binding

> Note that this particular test ensures FAR GREATER OVERHEAD for the binding being rebuilt
> as opposed to its internal caching and fast-tracking for a better result this was to simulate
> recreating the binding from scratch without the overhead of calling new on the constructor

```
TARGET = new enyo.Object({prop: "Shared"});
TARGET_TRANSFORM = function (v) { return v; };
TARGET_BINDING_KIND = enyo.kind({
kind: enyo.Binding,
rebuild: function () {
// ensure it will rebuild itself from the ground up
this.disconnect();
this.transform = "TARGET_TRANSFORM";
this.source = null;
this.target = null;
this._sourcePath = null;
this._sourceProperty = null;
this._sourceFrom = null;
this._targetPath = null;
this._targetProperty = null;
this._targetFrom = null;
this._sourceObserver = null;
this._targetObserver = null;
this.initTransform();
this.refresh();
}
})
enyo.kind({
name: "TARGET_KIND",
kind: enyo.Component,
defaultBindingKind: TARGET_BINDING_KIND,
components: [
{name: "child"}
],
bindings: [
{from: "^TARGET.prop", to: ".$.child.content", transform: "TARGET_TRANSFORM"}
]
});
var c = new TARGET_KIND();
var b = c.bindings[0];
var d = enyo.dev.bench({name: "getPath", average: true, autoStart: false, logging: false});
for (i=0; i<1000; ++i) {
d.start();
b.rebuild();
d.stop();
}
enyo.dev.report("getPath");
```

#### New getPath

```
- - - - - - - - - - - - - - - - -
BENCHMARK REPORT (averages): getPath
TOTAL TIME (ms): 36.4360000094166
AVERAGE TIME (ms): 0.0364360000094166
MINIMUM TIME (ms): 0.027999998565064743
MAXIMUM TIME (ms): 1.0050000018964056
NUMBER OF ENTRIES: 1000
- - - - - - - - - - - - - - - - -
```

#### Old getPath

```
- - - - - - - - - - - - - - - - -
BENCHMARK REPORT (averages): getPath
TOTAL TIME (ms): 69.66899999315501
AVERAGE TIME (ms): 0.06966899999315501
MINIMUM TIME (ms): 0.043000000005122274
MAXIMUM TIME (ms): 2.494000000297092
NUMBER OF ENTRIES: 1000
- - - - - - - - - - - - - - - - -
```

Enyo-DCO-1.1-Signed-off-by: Cole Davis