typed array filling convenience AND performance
The usecases: *1) Filling with custom data* When writing WebGL or physics or many other things todo with large collections of data, it's not unusual to have to fill arrays with custom data of some kind. someArray.set([ x0, y0, 1, 0, 0, x1, y0, 0, 1, 0, x1, y1, 0, 0, 1, x0, y0, 1, 0, 0, x1, y1, 0, 1, 0, x0, y1, 0, 0, 1 ], i); *2) Copying in data from another array* Some data resides in another array and needs to be copied in. A feature frequently in use by emscripten. someArray.set(otherArray.subarray(srcOffset, srcSize), dstOffset) *3) Initializing an existing array with a repeated numerical value* For audio processing, physics and a range of other tasks it's important to initialize an array with the same data. for(var i=0; isize; i++){ someArray[i] = 0; } *The problem:* Doing all of these things is slow and/or unsuitable for realtime code. 1. someArray.set from a new list is slow due to set being slow, and constructing the list is slow. It's not realtime friendly because it'll construct a new list, which will have to be GCed. 2. someArray.set is slow due to the new array view construction and it's not realtime friendly due to GCing. 3. Filling an array one element at a time is slow. *The test: *http://jsperf.com/typed-array-fast-filling/4 (screenshot here http://codeflow.org/pictures/typed-array-test.png and attached) *The status quo:* The fastest way to fill an array with custom data across browsers is: r[i] = x0; r[i + 1] = y0; r[i + 2] = 1; r[i + 3] = 0; r[i + 4] = 0; r[i + 5] = x1; r[i + 6] = y0; *Things that are not faster: * - pushing to a list: ~93% slower - a helper function filling from a list: 57-70% slower - array.set: ~73% slower - a helper function filling from arguments: 65% - 93% slower - asm.js: 69-81% slower (even in firefox) *Suggestions:* 1. Browser engines should get a lot better at arguments handling so that non sized arguments can be quickly iterated by native code. Firefox is already pretty good at unboxing a specified argument list (chrome not so much), but I think that test shows that there's ample room for improvement. 2. *someArray.memcpy*: Add a method to typed arrays that can shuffle bytes from array A to array B like so: dst.memcpy(dstOffset, src, srcOffset, size). This is to avoid having to allocate an object to do the job. 3. *someArray.memset*: Add a method to typed arrays that can initialize them with a value like so: dst.memset(dstOffset, value, size) 4. *someArray.argcpy*: Add a (fast) method to typed arrays that can copy the arguments like so: dst.argcpy(dstOffset, 1, 2, 3, 4) 5. Drastically improve the set method. (naming and semantic don't matter to me, long as the methods do it efficiently, conveniently and fast what's suggested). *Related discussion:* - https://bugzilla.mozilla.org/show_bug.cgi?id=936168 - https://www.khronos.org/webgl/public-mailing-list/archives/1410/msg00105.html *Consequence of failure to rectify:* Fast code will be unreadable and unmaintainable. Sophisticated and speed requiring code will not be written in ecmascript. Emscripten and asm.js with its hermetic nature will crowd out ecmascript driven developments. Other alternatives such as on GPU transformfeedback and compute shaders will be preferred to solve the problem. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Proposal: Abstract References
On 29 October 2014 21:59, Mark S. Miller erig...@google.com wrote: On Wed, Oct 29, 2014 at 8:16 AM, Andreas Rossberg rossb...@google.com wrote: On 27 October 2014 16:50, Tom Van Cutsem tomvc...@gmail.com wrote: 2014-10-27 15:00 GMT+01:00 Andreas Rossberg rossb...@google.com: but without breaking membrane transparency. I'm still not sure I understand how this affects membranes specifically. A membrane would never pass a proxied object to a non-proxied function from the same side. So functions accessing (or testing for) private state on an object are a non-issue in that scenario, because this access never crosses the membrane, does it? After all, membranes work just fine with builtins or host objects (otherwise they would be useless). I believe what Mark was referring to is the fact that if a WeakMap crosses the membrane, it gets proxied. Manipulating the WeakMap using WeakMap.prototype.{get,set} subsequently allows the membrane to intercept and wrap those operations. Sure, I understand. However, my point was that in the usual private state scenario, the weak map / private symbol _itself_ would never actually cross the membrane. All its uses are encapsulated on one side. So at least ordinary private state via private properties (e.g. as part of a class abstraction) is not actually an issue for membranes. Or am I missing something? Yes. We're talking about class-private instance state, not instance-private instance state, so one instance can be asked about another alleged instance. Yes, that's what I am talking about as well. Maybe I'm being dense, but again, where does class-private instance state require a private name / weak map to go _through_ a membrane? Any legal instance would always originate from the same side, i.e., would be unproxied when encountered by a method. So accessing the private state works where it should work. Symmetrically, as long as proxies simply signal absence of private fields (without leaking private symbols to any trap), it also works correctly (i.e., fails) to ask a non-instance about private fields. As I said, this would really be the exact same model as we already have for built-in / host internal state. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: typed array filling convenience AND performance
+1 - especially the lack of something like the proposed memset() has been a massive headache for me. Semantics (I'm quite nitpicky on them)... I'd prefer the argument order for memcpy() to be (src, dstOffset, srcOffset, size) to be consistent with set(). As for memset(), I'd prefer (value, dstOffset, size) because I've so far actually never needed offset and size. I'd also prefer memcpy to be named closer to set(), because it's basically the same thing with two extra arguments. I'm not sure what the performance implications would be to actually just add the extra two parameters to set as optional, so maybe someone smarter than me can chime in on whether it's better to add a separate method or overload the existing set()? It's worth noting that set() currently gets relatively faster the bigger the data is, and the last I tested (also confirmed by Jukka Jylänki), at around 4k (surprisingly many) elements it becomes faster than manually assigning values. On Thu, Oct 30, 2014 at 10:29 AM, Florian Bösch pya...@gmail.com wrote: The usecases: *1) Filling with custom data* When writing WebGL or physics or many other things todo with large collections of data, it's not unusual to have to fill arrays with custom data of some kind. someArray.set([ x0, y0, 1, 0, 0, x1, y0, 0, 1, 0, x1, y1, 0, 0, 1, x0, y0, 1, 0, 0, x1, y1, 0, 1, 0, x0, y1, 0, 0, 1 ], i); *2) Copying in data from another array* Some data resides in another array and needs to be copied in. A feature frequently in use by emscripten. someArray.set(otherArray.subarray(srcOffset, srcSize), dstOffset) *3) Initializing an existing array with a repeated numerical value* For audio processing, physics and a range of other tasks it's important to initialize an array with the same data. for(var i=0; isize; i++){ someArray[i] = 0; } *The problem:* Doing all of these things is slow and/or unsuitable for realtime code. 1. someArray.set from a new list is slow due to set being slow, and constructing the list is slow. It's not realtime friendly because it'll construct a new list, which will have to be GCed. 2. someArray.set is slow due to the new array view construction and it's not realtime friendly due to GCing. 3. Filling an array one element at a time is slow. *The test: *http://jsperf.com/typed-array-fast-filling/4 (screenshot here http://codeflow.org/pictures/typed-array-test.png and attached) *The status quo:* The fastest way to fill an array with custom data across browsers is: r[i] = x0; r[i + 1] = y0; r[i + 2] = 1; r[i + 3] = 0; r[i + 4] = 0; r[i + 5] = x1; r[i + 6] = y0; *Things that are not faster: * - pushing to a list: ~93% slower - a helper function filling from a list: 57-70% slower - array.set: ~73% slower - a helper function filling from arguments: 65% - 93% slower - asm.js: 69-81% slower (even in firefox) *Suggestions:* 1. Browser engines should get a lot better at arguments handling so that non sized arguments can be quickly iterated by native code. Firefox is already pretty good at unboxing a specified argument list (chrome not so much), but I think that test shows that there's ample room for improvement. 2. *someArray.memcpy*: Add a method to typed arrays that can shuffle bytes from array A to array B like so: dst.memcpy(dstOffset, src, srcOffset, size). This is to avoid having to allocate an object to do the job. 3. *someArray.memset*: Add a method to typed arrays that can initialize them with a value like so: dst.memset(dstOffset, value, size) 4. *someArray.argcpy*: Add a (fast) method to typed arrays that can copy the arguments like so: dst.argcpy(dstOffset, 1, 2, 3, 4) 5. Drastically improve the set method. (naming and semantic don't matter to me, long as the methods do it efficiently, conveniently and fast what's suggested). *Related discussion:* - https://bugzilla.mozilla.org/show_bug.cgi?id=936168 - https://www.khronos.org/webgl/public-mailing-list/archives/1410/msg00105.html *Consequence of failure to rectify:* Fast code will be unreadable and unmaintainable. Sophisticated and speed requiring code will not be written in ecmascript. Emscripten and asm.js with its hermetic nature will crowd out ecmascript driven developments. Other alternatives such as on GPU transformfeedback and compute shaders will be preferred to solve the problem. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: typed array filling convenience AND performance
Have you looked at the ES6 typed array constructor http://people.mozilla.org/~jorendorff/es6-draft.html#sec-properties-of-the-%typedarray%-intrinsic-object and instance methods http://people.mozilla.org/~jorendorff/es6-draft.html#sec-properties-of-the-%typedarrayprototype%-object In particular check out the from, copyWith, and fill methods. In general, TC39’s approach in ES6 is for typed arrays to simply be a variant of Array and all of the Array methods (except those that are not applicable to fixed length arrays) are supported for typed arrays. Similarly, if there are common array operations that are still missing we would want them to be added for both Array and typed arrays. Performance optimizatiuon in an implementation issues. That’s where you should apply performance pressure. Allen___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: typed array filling convenience AND performance
On Thu, Oct 30, 2014 at 3:14 PM, Adrian Perez de Castro ape...@igalia.com wrote: On Thu, 30 Oct 2014 09:29:36 +0100, Florian Bösch pya...@gmail.com wrote: The usecases: [...] *3) Initializing an existing array with a repeated numerical value* For audio processing, physics and a range of other tasks it's important to initialize an array with the same data. for(var i=0; isize; i++){ someArray[i] = 0; } For this use case there is %TypedArray%.prototype.fill(), see: Oh, nice! Had completely missed fill() before. Hope to see this land soon. :) http://people.mozilla.org/~jorendorff/es6-draft.html#sec-%typedarray%.prototype.fill JavaScript engines are expected to implement it at some point. For example I am implementing this in V8, along with other new typed array methods. The engines should be able to generate quite good code for uses of this function and/or provide optimized versions relying on knowledge of the underlying element type of the typed array they are applied to. Cheers, -- ☺ Adrián ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: typed array filling convenience AND performance
On Thu, Oct 30, 2014 at 1:41 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: Performance optimizatiuon in an implementation issues. That’s where you should apply performance pressure. That's true, but if there's only bad APIs to do certain tasks, it doesn't help. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: typed array filling convenience AND performance
On 10/30/2014 06:14 AM, Adrian Perez de Castro wrote: On Thu, 30 Oct 2014 09:29:36 +0100, Florian Bösch pya...@gmail.com wrote: The usecases: [...] *3) Initializing an existing array with a repeated numerical value* For audio processing, physics and a range of other tasks it's important to initialize an array with the same data. for(var i=0; isize; i++){ someArray[i] = 0; } For this use case there is %TypedArray%.prototype.fill(), see: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-%typedarray%.prototype.fill JavaScript engines are expected to implement it at some point. For example I am implementing this in V8, along with other new typed array methods. The engines should be able to generate quite good code for uses of this function and/or provide optimized versions relying on knowledge of the underlying element type of the typed array they are applied to. I implemented this for Firefox 2 years ago, but never landed it - https://bugzilla.mozilla.org/show_bug.cgi?id=730880 Now there is %TypedArray%.prototype.fill. But I've become generally skeptical about it as an answer to performance concerns. I would rather see engines hyperoptimize for(var i=0; isize; i++){ someArray[i] = 0; } based on observed type information. Which is not to say that we wouldn't want to make TA#fill fast too, but the above seems more generally useful. On a related note, I *would* like to have some way of getting the OS to decommit memory. See https://bugzilla.mozilla.org/show_bug.cgi?id=855669 (start reading at about comment 22) for our discussion and attempt at this, which looks like it mysteriously trailed off this last March. Theoretically, the above loop could also trigger a decommit, but I think it's too much to expect the engine to guess when that's going to be a good idea. On the other hand, from a spec POV it's unobservable behavior, which makes it weird. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: typed array filling convenience AND performance
On Oct 30, 2014, at 10:44 AM, Steve Fink sph...@gmail.com wrote: On 10/30/2014 06:14 AM, Adrian Perez de Castro wrote: On Thu, 30 Oct 2014 09:29:36 +0100, Florian Bösch pya...@gmail.com wrote: The usecases: [...] *3) Initializing an existing array with a repeated numerical value* For audio processing, physics and a range of other tasks it's important to initialize an array with the same data. for(var i=0; isize; i++){ someArray[i] = 0; } For this use case there is %TypedArray%.prototype.fill(), see: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-%typedarray%.prototype.fill JavaScript engines are expected to implement it at some point. For example I am implementing this in V8, along with other new typed array methods. The engines should be able to generate quite good code for uses of this function and/or provide optimized versions relying on knowledge of the underlying element type of the typed array they are applied to. I implemented this for Firefox 2 years ago, but never landed it - https://bugzilla.mozilla.org/show_bug.cgi?id=730880 https://bugzilla.mozilla.org/show_bug.cgi?id=730880 Now there is %TypedArray%.prototype.fill. But I've become generally skeptical about it as an answer to performance concerns. I would rather see engines hyperoptimize for(var i=0; isize; i++){ someArray[i] = 0; } based on observed type information. Which is not to say that we wouldn't want to make TA#fill fast too, but the above seems more generally useful. I agree with this philosophy. I would just point out that both in C and Java, having some way for the programmer to say “fill” (i.e. memset/bzero in C, and I forget what it is in Java) has survived despite the compilers being super mature, probably because idiom recognition on loops like this is too fallible in the general case. So, I’d like to see .fill() be part of the language. Anyway, I just filed a bug on our end for this: https://bugs.webkit.org/show_bug.cgi?id=138218 -Filip On a related note, I *would* like to have some way of getting the OS to decommit memory. See https://bugzilla.mozilla.org/show_bug.cgi?id=855669 https://bugzilla.mozilla.org/show_bug.cgi?id=855669 (start reading at about comment 22) for our discussion and attempt at this, which looks like it mysteriously trailed off this last March. Theoretically, the above loop could also trigger a decommit, but I think it's too much to expect the engine to guess when that's going to be a good idea. On the other hand, from a spec POV it's unobservable behavior, which makes it weird. ___ es-discuss mailing list es-discuss@mozilla.org mailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: typed array filling convenience AND performance
On Thu, Oct 30, 2014 at 6:44 PM, Steve Fink sph...@gmail.com wrote: Now there is %TypedArray%.prototype.fill. But I've become generally skeptical about it as an answer to performance concerns. I would rather see engines hyperoptimize for(var i=0; isize; i++){ someArray[i] = 0; } based on observed type information. Which is not to say that we wouldn't want to make TA#fill fast too, but the above seems more generally useful. While useful, it's not a substitute for a convenient and fast method. Also, I presented severe usuability issues with that approach if you need more than one value (such as computed values). Usability issues which can be resolved by using set + a new list for every assignment, which, unfortunately, is also quite slow. It's slow because say, for a loop that's running a million times, it makes a million lists. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Types
Hello, Isn't optional typing (similar to TypeScript) a good thing? Let's say I want to do some image processing. And images can be really huge nowadays. If I allocate an array of dynamic variables, that array may be 10x larger than if it was an array of bytes. And I need bytes to store and process R,G,B,A values separately. So, the array itself could have a descriptor of the type, and each member of the array can then contain only the value. As things are now, a 32 megapixel image in ES would allocate 32,000,000 x 4 = 128 million dynamic variables. If each variant takes up 8 bytes, that's 1 GB per image. Let's say I have two source images, one mask and one output. That's 4 gigabytes just in images, not counting the application, libraries, web browser, other running apps, OS, drivers, etc. That's a waste of resources. Native apps would need only about 0.5 GB for all 4 source images, so it would run on a wide variety of devices as opposed to the ES variant. And thus the author would sell more copies and earn more money. Instead of getting comments like Why did you made this crappy slow app. Learn to program. Competition is much faster. If ES is to become a proper, truly versatile language, shouldn't programmer be allowed to use it's knowledge of the app design to optimize resources? Best regards, Zex ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Types
Use typed arrays. From: Zexxmailto:zex2...@gmail.com Sent: 2014-10-30 20:16 To: es-discuss@mozilla.orgmailto:es-discuss@mozilla.org Subject: Types Hello, Isn't optional typing (similar to TypeScript) a good thing? Let's say I want to do some image processing. And images can be really huge nowadays. If I allocate an array of dynamic variables, that array may be 10x larger than if it was an array of bytes. And I need bytes to store and process R,G,B,A values separately. So, the array itself could have a descriptor of the type, and each member of the array can then contain only the value. As things are now, a 32 megapixel image in ES would allocate 32,000,000 x 4 = 128 million dynamic variables. If each variant takes up 8 bytes, that's 1 GB per image. Let's say I have two source images, one mask and one output. That's 4 gigabytes just in images, not counting the application, libraries, web browser, other running apps, OS, drivers, etc. That's a waste of resources. Native apps would need only about 0.5 GB for all 4 source images, so it would run on a wide variety of devices as opposed to the ES variant. And thus the author would sell more copies and earn more money. Instead of getting comments like Why did you made this crappy slow app. Learn to program. Competition is much faster. If ES is to become a proper, truly versatile language, shouldn't programmer be allowed to use it's knowledge of the app design to optimize resources? Best regards, Zex ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Types
http://people.mozilla.org/~jorendorff/es6-draft.html#sec-typedarray-objects On Oct 30, 2014, at 9:27 PM, Domenic Denicola d...@domenic.me wrote: Use typed arrays. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Types
TypeScript is about static type checking (and IDE support), what you want dynamic types that are better fits for problem domains. This is a step in that direction (in addition to typed arrays in ES6): https://github.com/dslomov-chromium/typed-objects-es7 https://github.com/dslomov-chromium/typed-objects-es7 On 31 Oct 2014, at 01:15, Zexx zex2...@gmail.com mailto:zex2...@gmail.com wrote: Hello, Isn't optional typing (similar to TypeScript) a good thing? Let's say I want to do some image processing. And images can be really huge nowadays. If I allocate an array of dynamic variables, that array may be 10x larger than if it was an array of bytes. And I need bytes to store and process R,G,B,A values separately. So, the array itself could have a descriptor of the type, and each member of the array can then contain only the value. As things are now, a 32 megapixel image in ES would allocate 32,000,000 x 4 = 128 million dynamic variables. If each variant takes up 8 bytes, that's 1 GB per image. Let's say I have two source images, one mask and one output. That's 4 gigabytes just in images, not counting the application, libraries, web browser, other running apps, OS, drivers, etc. That's a waste of resources. Native apps would need only about 0.5 GB for all 4 source images, so it would run on a wide variety of devices as opposed to the ES variant. And thus the author would sell more copies and earn more money. Instead of getting comments like Why did you made this crappy slow app. Learn to program. Competition is much faster. If ES is to become a proper, truly versatile language, shouldn't programmer be allowed to use it's knowledge of the app design to optimize resources? Best regards, Zex ___ es-discuss mailing list es-discuss@mozilla.org mailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Dr. Axel Rauschmayer a...@rauschma.de mailto:a...@rauschma.de rauschma.de ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss