Properties vs. Attributes: which to use, and when?

Showing 1-14 of 14 messages
Properties vs. Attributes: which to use, and when? Eric Ferraiuolo 2/14/13 10:50 AM
I would like to bring up the discussion of choosing when to use properties vs. attributes.

The most recent occurrence of this discussion is on the Y.Tree pull request:

  * https://github.com/yui/yui3/pull/429#discussion_r2913389
  * https://github.com/yui/yui3/pull/429#discussion_r2913400
  * https://github.com/yui/yui3/pull/429#issuecomment-13562228

I think we need to figure out a best practice here that promotes API consistency and predictability, while also having a reasonable performance profile.

----

Here's how the usage of properties vs. attributes breaks down for me:

I use properties to hold class-level state and configuration—stuff which is generally shared between all instances of the class. If the general use is for all instances to use a shared value, then I make it a property.

I use attributes to hold per-instance state and configuration—stuff which is generally specified for every instance and not likely to be shared across all instances. If every instance is configured with a unique value, I see attributes being a better fit than properties.

Y.View great example of a component which uses both properties and attributes:

View Properties:

  * containerTemplate
  * events
  * template

These values are generally shared across all instances of a view subclass. They may also be overridden when creating a new instance. In the case of `events`, each instance gets its own copy, which is a merge of the prototype value with the instance's config value.

View Attributes:

  * container
  * destroyed (inherited)
  * initialized (inherited)

Each view instance *always* gets its own value for these attributes, the values are never shared across instances.

Per-instance state and configuration is more likely to need getter/setter, validation, and change notifications all of which attributes provides. When looking to the future and having Y.Attribute leverage ES 5/6 language features, its `get/set()` abstraction becomes highly valuable as it hides the implementation details and maintains backwards compatibility with older browsers. In fact I'd go as far as to say naked (not going through methods) property getters/setters are a bad design for use in high level APIs. When using ES 5 getters/setters a simple property assignment could have unknown costs and side effects, while the use of `get/set()` methods communicate these potential costs and side effects.

----

A common argument is that attributes can be slow and therefore the abstraction is too costly. Recently, we've been working hard to address this: https://github.com/yui/yui3/pull/453

Current `get/set()` Performance (no change events):

  * get x 8,051,731 ops/sec ±2.20% (95 runs sampled)
  * set x 1,845,308 ops/sec ±1.22% (96 runs sampled)

3.8.1 `get/set()` Performance (no change events):

  * get x 2,044,074 ops/sec ±1.71% (97 runs sampled)
  * set x 434,217 ops/sec ±1.67% (91 runs sampled)

These are drastic improvements to value access and assignment! And I understand this is no where near the performance simple property access and assignment, but for most cases, in our higher level APIs, attributes should be fast enough to warrant the cost of their abstraction.

----

Thoughts? Comments? Also, I'm not trying to single out Ryan; his Y.Tree is actually a great context in which to have this discussion as it shows all sides of the tradeoffs.


Eric

Re: [yui-contrib] Properties vs. Attributes: which to use, and when? Ryan Grove 2/14/13 11:28 AM
I can't reply in detail right now as I am literally on the road to a snowy cabin in the mountains, but I have very strong opinions on this topic. I'll try to boil them down to something I can type on my iPhone:

I use attributes when I need setters, getters, or change events. I never use attributes solely for consistency. That's about the gist of it. This reasoning would still apply even if attributes were using ES5/6 native functionality under the hood.

Properties are a perfectly wonderful language feature that we should embrace when they meet our needs.

- Ryan
--
You received this message because you are subscribed to the Google Groups "yui-contrib" group.
To unsubscribe from this group and stop receiving emails from it, send an email to yui-contrib...@googlegroups.com.
To post to this group, send email to yui-c...@googlegroups.com.

Re: Properties vs. Attributes: which to use, and when? Steven Olmsted 2/14/13 11:54 AM
I feel like the performance costs of attribute are the main reason to use properties.  If attribute was free, why use properties ever?  The performance improvements to attribute are a really great point in favor of using attribute.  Yet you only mention the cost of get/set.  Aren't there more substantial costs per attribute at instantiation time and/or the moment of first access per instance?

Also you only mentioned performance without change events.  Change events seem to me to be the number one reason for using attribute.  Compared to the number of times I've used change events, it's extremely rare for me to use getters and/or setters.  Many of my YUI 3 classes have writeOnce: 'initOnly' attributes.  Something to configure an instance at instantiation, but it's not expected to ever change.  As I update my code, I have been converting these to properties.  If the value never changes, or if I'm not at all interested in change events, and I have no getter or setter, why am I using attribute?  Attribute isn't free; if none of attribute's features will be in use, I'd prefer making it a property instead.

Something feels odd to me about using prototype properties for class-level state.  If I'm using `this.something` or `instance.something` to access a value, I assume I'm accessing per-instance state.  I would put class-level state in @static properties on the class.

I completely agree with your point about ES5 getters/setters in public APIs.  If I'm using `instance.something` to access a value, I don't want that to start a complex procedure or have side effects.  Yet I've broken that rule in @protected APIs: https://github.com/solmsted/yui3-gallery-2/blob/master/src/gallery-composite-image/js/composite-image.js#L571-L598
Re: [yui-contrib] Properties vs. Attributes: which to use, and when? Karl Guertin 2/14/13 12:10 PM
On Thu, Feb 14, 2013 at 1:50 PM, Eric Ferraiuolo <eferr...@gmail.com> wrote:
Thoughts? Comments? Also, I'm not trying to single out Ryan; his Y.Tree is actually a great context in which to have this discussion as it shows all sides of the tradeoffs.

Decision point for me is to attribute when something needs to be configurable at instantiation or needs a getter/setter or change event. We don't even think about them for consistency because the attribute/event system performs so poorly.
Re: [yui-contrib] Properties vs. Attributes: which to use, and when? Eric Ferraiuolo 2/14/13 12:37 PM
On Feb 14, 2013, at 2:54 PM, Steven Olmsted <steve...@gmail.com> wrote:

Yet you only mention the cost of get/set.  Aren't there more substantial costs per attribute at instantiation time and/or the moment of first access per instance?

Also you only mentioned performance without change events.  Change events seem to me to be the number one reason for using attribute.  Compared to the number of times I've used change events, it's extremely rare for me to use getters and/or setters.

Yes, I know, that's why I included a link to the pull request which has more details on the benchmarks.

Something feels odd to me about using prototype properties for class-level state.  If I'm using `this.something` or `instance.something` to access a value, I assume I'm accessing per-instance state.  I would put class-level state in @static properties on the class.

I guess a better way of putting it was to use prototype properties to provide *defaults* for things which are generally shared by all instances.


Eric

--
You received this message because you are subscribed to the Google Groups "yui-contrib" group.
To unsubscribe from this group and stop receiving emails from it, send an email to yui-contrib...@googlegroups.com.
To post to this group, send email to yui-c...@googlegroups.com.
Visit this group at http://groups.google.com/group/yui-contrib?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Re: [yui-contrib] Properties vs. Attributes: which to use, and when? Karl Guertin 2/14/13 1:02 PM
On Thu, Feb 14, 2013 at 3:37 PM, Eric Ferraiuolo <eferr...@gmail.com> wrote:
Yes, I know, that's why I included a link to the pull request which has more details on the benchmarks.

Is there interest in a Model with the same config API but different semantics? I spent last weekend writing one that I'd intended for Squarespace internal use. Uses Knockout's observables (hacked out of the rest of KO, ~12k minified and 3k gz) for events, uses .create() to do new model instances with attribute objects that have the parent as their prototype.

It's incomplete so these numbers might go down but I get about 40M ops/s in Chrome 26 on my `x.set('a', x.get('a') + 1)` micro benchmark versus 200M for a raw property and 1.6M ops/s running through a subscriber. Firefox 20 is 8M, 150M, and 200K respectively.

Since the yui community is relatively API conservative, I assumed most people wouldn't be interested but we really need the perf for the heavier parts of our system.
Re: [yui-contrib] Properties vs. Attributes: which to use, and when? Ryan Grove 2/14/13 6:43 PM
On Thursday, February 14, 2013 at 1:02 PM, Karl Guertin wrote:
Is there interest in a Model with the same config API but different semantics? I spent last weekend writing one that I'd intended for Squarespace internal use. Uses Knockout's observables (hacked out of the rest of KO, ~12k minified and 3k gz) for events, uses .create() to do new model instances with attribute objects that have the parent as their prototype.
We definitely need to make Models faster and lighter (probably by ripping Base out from under them, unless Base can get much, much faster), but this sounds like a lot of duplication for YUI. Could make a good gallery module though.

It's incomplete so these numbers might go down but I get about 40M ops/s in Chrome 26 on my `x.set('a', x.get('a') + 1)` micro benchmark versus 200M for a raw property and 1.6M ops/s running through a subscriber. Firefox 20 is 8M, 150M, and 200K respectively.
Nice!

- Ryan
Re: [yui-contrib] Properties vs. Attributes: which to use, and when? Juan Ignacio Dopazo 2/15/13 4:34 AM
Models could be made faster by killing attribute based changed events, only keeping the "global" change event and making it async. Sort of a polyfill for Object.observe().

I the issue in this thread mostly comes down to a style decision. So far I've seen YUI use mostly attributes and private properties, rarely a public property. The only one I remember (ignoring plugins and a fair amount of prototype properties) is "data" in DataTable. That said, I agree with Eric's opinion here.

Juan
Re: [yui-contrib] Properties vs. Attributes: which to use, and when? Satyam 2/15/13 9:15 AM

On 02/15/2013 03:43 AM, Ryan Grove wrote:
On Thursday, February 14, 2013 at 1:02 PM, Karl Guertin wrote:
Is there interest in a Model with the same config API but different semantics? I spent last weekend writing one that I'd intended for Squarespace internal use. Uses Knockout's observables (hacked out of the rest of KO, ~12k minified and 3k gz) for events, uses .create() to do new model instances with attribute objects that have the parent as their prototype.
We definitely need to make Models faster and lighter (probably by ripping Base out from under them, unless Base can get much, much faster), but this sounds like a lot of duplication for YUI. Could make a good gallery module though.
There is a gallery-md-model there, which doesn't use Attributes for the data.  Admittedly, it never went much beyond a prototype and still uses Base, but not for the data, which is the heaviest part.

It's incomplete so these numbers might go down but I get about 40M ops/s in Chrome 26 on my `x.set('a', x.get('a') + 1)` micro benchmark versus 200M for a raw property and 1.6M ops/s running through a subscriber. Firefox 20 is 8M, 150M, and 200K respectively.
Nice!

- Ryan
--
You received this message because you are subscribed to the Google Groups "yui-contrib" group.
To unsubscribe from this group and stop receiving emails from it, send an email to yui-contrib...@googlegroups.com.
To post to this group, send email to yui-c...@googlegroups.com.
Visit this group at http://groups.google.com/group/yui-contrib?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Re: [yui-contrib] Properties vs. Attributes: which to use, and when? Standa Opichal 2/15/13 10:08 AM
Hi!

On Fri, Feb 15, 2013 at 3:43 AM, Ryan Grove <ry...@wonko.com> wrote:
We definitely need to make Models faster and lighter (probably by ripping Base out from under them, unless Base can get much, much faster), but this sounds like a lot of duplication for YUI. Could make a good gallery module though.


In my eyes YUI needs to fix the performance of its eventing and consequently all the Y.Attribute-based stuff which would make it have less performance issues. Once you hit the performance issues there is currently not much one can do about them. Especially in slower browsers on older, but still supported operating systems.

Best Regards
Standa Opichal

Re: [yui-contrib] Properties vs. Attributes: which to use, and when? Ryan Grove 2/15/13 10:32 AM
On Friday, February 15, 2013 at 4:34 AM, Juan Ignacio Dopazo wrote:
Models could be made faster by killing attribute based changed events, only keeping the "global" change event and making it async. Sort of a polyfill for Object.observe().
That's not the main performance killer in Model. Base instantiation and memory cost are by far the biggest pain points. Attribute change events and access costs are relatively minor in comparison (although I agree that they are still suboptimal).

I the issue in this thread mostly comes down to a style decision. So far I've seen YUI use mostly attributes and private properties, rarely a public property. The only one I remember (ignoring plugins and a fair amount of prototype properties) is "data" in DataTable. That said, I agree with Eric's opinion here.
Style has very little to do with it in my case. It's more about not doing more work than is necessary. In many cases, properties meet my needs; using an attribute when a property would suffice would mean doing unnecessary work that adds no value to my code.

The primary value of most abstractions is in code reuse. Consistency is a secondary benefit. All abstractions have a cost, and the benefit of code reuse generally justifies that cost. When the cost of the abstraction is low, using the abstraction solely for the sake of consistency isn't such a bad thing. But when the cost of the abstraction is relatively high, as it is in the case of attributes vs. properties, using that abstraction solely for consistency and not for any other benefit is a bad idea.

In the long term, as we reduce the cost of using attributes by improving the implementation, it will become less harmful to use attributes solely for the sake of API consistency. We're not there yet, though.

- Ryan
Re: [yui-contrib] Properties vs. Attributes: which to use, and when? Manuel Jasso 2/16/13 10:23 AM
<< In the long term, as we reduce the cost of using attributes by improving the implementation, it will become less harmful to use attributes solely for the sake of API consistency. We're not there yet, though. >>

Totally agree. Use attributes when you need the event system and not merely for consistency, unless the performance penalty is negligible. Hopefully this can be fixed!
 
~Manuel


From: Ryan Grove <ry...@wonko.com>
To: yui-c...@googlegroups.com
Sent: Friday, February 15, 2013 10:32 AM
Subject: Re: [yui-contrib] Properties vs. Attributes: which to use, and when?

--
You received this message because you are subscribed to the Google Groups "yui-contrib" group.
To unsubscribe from this group and stop receiving emails from it, send an email to yui-contrib...@googlegroups.com.
To post to this group, send email to yui-c...@googlegroups.com.
Visit this group at http://groups.google.com/group/yui-contrib?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 


Re: Properties vs. Attributes: which to use, and when? Matt Parker 2/21/13 2:17 AM
Sorry this is a bit behind the times, I've been mulling for a few days.

I think API consistency is being under-valued here, for library code anyway.

In general I'd expect properties to be protected, and attributes to be public.  I remember wasting enough time for me still to remember it debugging something in YUI2, and realising it was something.cfg.getProperty("else") instead of get("else").  Having to look up API docs all the time for things that *should* just be something.get("else") is a waste of developers time, and as a wiser man than I has said a few times, developer time needs to be optimised too.

The next bit is is a guess that may be wrong...  In general, Attributes are (relatively) rarely touched by the end user: there will be some initial config, and some listeners, but we're talking a handful of calls to get/set etc.  The cost of Attribute comes from the internal use of it.  So if that's true, and if it makes sense to the internals of the component to have it as a property, rather than an attribute, then do that.  But if it needs to be public, create an Attribute whose getter/setter point to the property, and make the property private.  The component internally uses the property, and gains the performance, but for me in userland I get the consistent API, which I value a lot.

The big disadvantage of this is that when the component changes the value of a property, no change event will be fired (although that's trivially true with properties anyway, so the designer of the component clearly thinks that it's not something that will ever need a change event, or useful events are provided elsewhere).  But by providing Attribute API access to it perhaps I'd expect it to.  I don't know if documentation is the answer to this - perhaps it's just creating a similar version of the same problem (now I need to go and read to docs to see if it's @observable or not).  But given that Attribute is now broken up, perhaps it would be a good thing to add an 'observable' property in the ATTRS config literal (default true) so that Attributes can be more finely tuned for performance by setting it to false (though I acknowledge this isn't the main performance issue).  From an API perspective, that would create a clearer understanding that just because it's in ATTRS doesn't immediately mean it fires change events.

Even if this is all wrong, I'd still like a +1 for consistency!

Matt
Re: Properties vs. Attributes: which to use, and when? Satyam 2/21/13 6:01 AM


On Thursday, February 21, 2013 11:17:33 AM UTC+1, Matt Parker wrote:
Sorry this is a bit behind the times, I've been mulling for a few days.

I think API consistency is being under-valued here, for library code anyway.

I agree with Matt on both accounts.  I am sorry as well, because I've been thinking about this for a while and couldn't find a way to start writing about it and, of course, I agree about consistency.  I also suffered the discrepancy in coding standards in between YUI2 Element-based widgets,  TreeView (which followed neither standard), the rest of the widgets and all the rest that weren't widgets.

I find myself having to go and check the docs more and more, just like it was in those days.   More and more of the new components are quite unpredictable in their choice of properties or attributes.  This not only forces the developer to check out the docs every single time, as there is no criteria for that choice and eventually hampers future development, as a choice on the basic component might not hold valid on subclasses someone might eventually develop.  Thus, if the original designer chooses a value to be stored in a property because he doesn't plan for any side-effects on the value being changed, someone might want a subclass where such a side-effect is produced, and is prevented from that. 

Actually, the choices are not limited to just properties vs. attributes, there is also the choice of public getters and setters methods with no attribute involved, I hope we don't get to that.

On the other hand, I heard that both Attribute and Event can be improved.  I've seen changes in Attribute because the component was split in several modules, I don't know what has been done with Event because it is not so obvious.  And I assume that in any case, none of those changes will be enough for those who want performance above all.

Then, perhaps it is time for YUI4?  If the core of the YUI3 library is not good then it might be time to plan for a new version.  Standardizing was not a minor consideration when YUI3 came out so that we could finally get out of the mess of so many families of components we had in YUI2.

Another solution might be to go for 'full-featured' and 'lite-and-fast'  components.  I suggested as much some time ago.  You need speed? go for the lite version.  Need all the features, go for the full version.  Like Handlebars and Y.Lang.sub.  But that is costly.

Having no architecture at all and building components with any mix and match of properties and attributes, or based on widget and/or view,  is becoming a complete mess, and an ever costlier one.