Non-extensibility of Typed Arrays

Filip Pizlo fpizlo at apple.com
Wed Sep 4 23:27:51 PDT 2013


On Sep 4, 2013, at 11:17 PM, Steve Fink <sphink at gmail.com> wrote:

> On 09/04/2013 04:15 PM, Filip Pizlo wrote:
>> 
>> On Sep 4, 2013, at 3:09 PM, Brendan Eich <brendan at mozilla.com> wrote:
>> 
>>>> Filip Pizlo <mailto:fpizlo at apple.com>
>>>> September 4, 2013 12:34 PM
>>>> My point is that having custom properties, or not, doesn't change the overhead for the existing typed array spec and hence has no effect on small arrays.  The reasons for this include:
>>>> 
>>>> - Typed arrays already have to be objects, and hence have a well-defined behavior on '=='.
>>>> 
>>>> - Typed arrays already have to be able to tell you that they are in fact typed arrays, since JS doesn't have static typing.
>>>> 
>>>> - Typed arrays already have prototypes, and those are observable regardless of expandability.  A typed array from one global object will have a different prototype than a typed array from a different global object.  Or am I misunderstanding the spec?
>>>> 
>>>> - Typed arrays already have to know about their buffer.
>>>> 
>>>> - Typed arrays already have to know about their offset into the buffer.  Or, more likely, they have to have a second pointer that points directly at the base from which they are indexed.
>>>> 
>>>> - Typed arrays already have to know their length.
>>>> 
>>>> You're not proposing changing these aspects of typed arrays, right?
>>> 
>>> Of course not, but for very small fixed length arrays whose .buffer is never accessed, an implementation might optimize harder.
>> 
>> As I said, of course you can do this, and one way you could "try harder" is to put the buffer pointer in a side table.  The side table maps array object pointers to their buffers, and you only make an entry in this table if .buffer is mentioned.
>> 
>> But if we believe that this is a sensible thing for a VM to do - and of course it is! - then the same thing can be done for the custom property storage pointer.
>> 
>>> It's hard for me to say "no, Filip's analysis shows that's never worthwhile, for all time."
>>> 
>>>> The super short message is this: so long as an object obeys object identity on '==' then you can have "free if unused, suboptimal if you use them" custom properties by using a weak map on the side.  This is true of typed arrays and it would be true of any other object that does object-style ==.  If you allocate such an object and never add a custom property then the weak map will never have an entry for it; but if you put custom properties in the object then the map will have things in it.  But with typed arrays you can do even better as my previous message suggests: so long as an object has a seldom-touched field and you're willing to eat an extra indirection or an extra branch on that field, you can have "free if unused, still pretty good if you use them" custom properties by displacing that field.  Typed arrays have both of these properties right now and so expandability is a free lunch.
>>> 
>>> The last sentence makes a "for-all" assertion I don't think implementations must be constrained by.
>> 
>> How so?  It is true that some VM implementations will be better than others.  But ultimately every VM can implement every optimization that every other VM has; in fact my impression is that this is exactly what is happening as we speak.
>> 
>> So, it doesn't make much sense to make language design decisions because it might make some implementor's life easier right now.  If you could argue that something will never be efficient if we add feature X, then that might be an interesting argument.  But as soon as we identify one sensible optimization strategy for making something free, I would tend to think that this is sufficient to conclude that the feature is free and there is no need to constrain it.  If we don't do this then we risk adding cargo-cult performance features that rapidly become obsolete.
> 
> This general argument bothers me slightly, because it assumes no opportunity cost in making something free(ish). Even if you can demonstrate that allowing X can be made fast, it isn't a complete argument for allowing X, since disallowing X might enable some other optimization or feature or semantic simplification.  Such demonstrations are still useful, since they can shoot down objections based solely on performance.
> 
> But maybe I'm misinterpreting "...sufficient to conclude...that there is no need to constrain [the feature]." Perhaps you only meant that there is no need to constrain it *for reasons of performance*? If so, then you only need consider the opportunity cost of other optimizations.

Yeah, I might have overstated this.  My gut intuition is that performance shouldn't be a great reason for deciding PL features to begin with.  But in the cases where you have the urge to add or remove a feature solely because of performance, I think that a sufficient counterargument is to show that there exists some sensible optimization strategy that obviates the feature (or its removal).  And yes, opportunity cost ought to be considered.  If you can make such a counterargument then probably the feature should be judged on its software engineering merits and not on performance merits.

My experience implementing free-if-unused custom properties on typed arrays was that it was a small hack with limited cost - I just relied on a lot of preexisting nastiness that we have to have, that was already there to deal with DOM semantics and to enable similar "free-if-unused" features for other objects.

-Filip

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130904/c9442d77/attachment-0001.html>


More information about the es-discuss mailing list