yui/yui3 — pull request #574 by sdesai (2013-04-01 20:11:34+00:00)
Title: Attribute and Base performance improvements

# Description

This is a set of 10 or so key commits (a lot of the others are merge commits, benchmark cleanups), aimed at optimizing normal `AttributeCore` and `BaseCore` operations (instantiation, get/set).

The changes are discussed in the context of `AttributeCore` and `BaseCore`, because it's a good way to isolate event from non-event costs. However anything we do for `AttributeCore` and `BaseCore`, also help `Attribute` and `Base`, as seen from the numbers below. For example, `ATTRS` aggregation, or `get()` work the same way regardless of event or no event. Working on them in the `AttributeCore/BaseCore` context, just helps highlight the changes without the event impact.

Individual commits as well as HISTORY.md have detailed information about the areas targeted, changes involved, and incremental performance improvements.

If you're interested in reviewing this, I would recommend reviewing the changes on a commit by commit basis, guided by the descriptions in each commit.

# Important Back-Compat Note

One of the key performance changes in this pull request is the change to cache the result of the static `ATTRS` aggregation which occurs when you instantiate a `Base` based object.

Prior to this pull request, we'd re-aggregate `ATTRS` for every instance created, which was where we spent about 1/3rd of the time required for `Base` instantiation. Now, for the 2nd instance onwards we re-use the cached aggregation improving performance substantially. Since `ATTRS` is a 'class' centric concept, that seemed reasonable.

However, as a result of this change, if you're touching the `ATTRS` collection on a 'class' directly, after it's first defined, there's potential for breakage (this seems to be rare - library code didn't have any such patterns). The cache won't know about your modifications if they come in after the first instance of that class is created. If you do have such code in your custom components, it will need to be changed to use the new `modifyAttrs()` static method. See Base's HISTORY.md for further details.

As part of the pull request (or preview release), we'd be interested if your code does in fact need to be updated to use the static `modifyAttrs`, and we'll refine the solution accordingly. We're hesitant to over-engineer it, without that input.

The related commits are:

https://github.com/sdesai/yui3/commit/699cc325d063aa44678ec3dbd9ac863f2b75d0b5
https://github.com/sdesai/yui3/commit/83f1e984dec53e4d14bc5744641405d224e069c7

# Numbers

On Chrome 25, compared to 3.8.1 (and probably 3.9.1), we're seeing the following improvements:

This branch:

Benchmark	x Change

new BaseCore()	3

basecore.set()	3

basecore.get()	4

Benchmark	x Change

new MyBaseCore() [extends BaseCore]	3

MyBaseCore with 10 simple value attributes	2

MyBaseCore with 20 varied attributes (using perf. best practices)	2

MyBaseCore with 10 simple value attributes - set()	3

MyBaseCore with 10 simple value attributes - get()	4

When combined with the work in https://github.com/yui/yui3/pull/572, we're seeing:

Benchmark	x Change

new Base()	4

base.set()	4

base.get()	5

# Testing

**All** library tests through `yogi test --no-cli` pass:

`[Total]: Passed: 10731 Failed: 0 Total: 10820 (ignored 89) (7 minutes, 59 seconds)`

Additionally **All** library tests pass on:

* IE8
* Safari6/Mac
* Safari6/iOS6
* FF19
* Chrome26

Aside from a couple of known testing and environment exceptions (jsonp/yeti, datatable date formatting/IE and a Y.clone(nodeInstance) bug, which @ericf has a fix for) which also fail on dev-3x.

# Preview And Release Timelines

Given the low-level nature of these changes, and the customizations on top of them, it would be beneficial to get a preview release based on these changes (event-perf-nolisteners + attrs-perf) out and have it get some real-world integration (especially for users with customizations on top of Base), with a week or two of reaction time prior to release, to clean up anything which comes up out of the pull requests and PR.