Typed Array Madness

50 views
Skip to first unread message

philogb

unread,
Jun 17, 2011, 3:12:09 PM6/17/11
to WebGL Dev List
I've been trying to optimize how typed arrays are used in PhiloGL. I
was thinking that instead of creating a new typed array instance each
time a uniform is to be set in a shader, just create an instance of a
typed array per uniform at the beginning of the application and then
use the `set` method of the typed array to set update the instance
before setting it with the gl call.

I thought that setting the typed array would be faster than creating a
new fresh typed array from scratch each time, and Firefox proves my
theory, but unfortunately Chrome behaves in a very very weird way.

In order to prove this, I created a simple test case that I share
here:

http://jsperf.com/typedarraysetvscreate/2

The results are crazy to say the least. Look at the number of ops/sec
when creating a fresh instance, assigning a value to the instance with
the set method and setting those same values via a for-loop. Could it
be that Chrome does not make any optimization for typed arrays? Could
anybody explain in more detail these results?

Thanks :)

Nicolas.

Cedric Pinson

unread,
Jun 17, 2011, 3:26:41 PM6/17/11
to webgl-d...@googlegroups.com
Hi,
I have the same problem, and right now I am using loop to fill it.
Waiting performance improves in chrome to switch of method.

Cedric

--
Cedric Pinson
Provide OpenGL, WebGL and OpenSceneGraph services
+33 659 598 614 - cedric...@plopbyte.com
http://plopbyte.com - http://osgjs.org - http://showwebgl.com

signature.asc

Kenneth Russell

unread,
Jun 17, 2011, 3:41:39 PM6/17/11
to webgl-d...@googlegroups.com
What is your question specifically?

In Chrome, yes, calling typed arrays' set() method with a JavaScript
array as argument is slow. Some recent work has been done -- see
http://crbug.com/84007 -- and some more is ongoing, but I am not sure
how much faster it can be made.

Element-by-element accesses have been highly optimized in V8 and more
optimizations continue there.

-Ken

philogb

unread,
Jun 17, 2011, 4:44:13 PM6/17/11
to WebGL Dev List
Hi Ken,

Thanks for your reply.

I guess my question is, how come a linear operation in javascript code
(for-loop) roughly equivalent to the set operation is so fast compared
to the same constant time operation in JS (the use of the set method)
in V8?

Also, I'm sure there should be more room for performance improvements
in the use of the set method in Chrome: FF5 is showing 55000 ops/sec
while Ch14 is showing 1100 (see comparison table below in
http://jsperf.com/typedarraysetvscreate/2 ).

Maybe I'm missing something?

PS: @Cedric Pinson: I'm not sure that is the best approach to be
taken, the experience in other browsers (Firefox for example) will be
downgraded. If you see for example FF5 statistics in the jsperf page,
you'll see that the set method is 5 times faster than a for-loop
assignment.

On Jun 17, 12:41 pm, Kenneth Russell <k...@chromium.org> wrote:
> What is your question specifically?
>
> In Chrome, yes, calling typed arrays' set() method with a JavaScript
> array as argument is slow. Some recent work has been done -- seehttp://crbug.com/84007-- and some more is ongoing, but I am not sure

Kenneth Russell

unread,
Jun 17, 2011, 6:47:35 PM6/17/11
to webgl-d...@googlegroups.com
On Fri, Jun 17, 2011 at 1:44 PM, philogb <phi...@gmail.com> wrote:
> Hi Ken,
>
> Thanks for your reply.
>
> I guess my question is, how come a linear operation in javascript code
> (for-loop) roughly equivalent to the set operation is so fast compared
> to the same constant time operation in JS (the use of the set method)
> in V8?

In both cases an element-by-element copy of the JavaScript array needs
to be made. When doing this copy in JavaScript, the V8 engine gets to
optimize the fetch of each JS array element and the store into the
typed array. When calling the set() method, each JS array element is
fetched using V8's C++ API -- see
http://trac.webkit.org/browser/trunk/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h
-- which is currently slow.

> Also, I'm sure there should be more room for performance improvements
> in the use of the set method in Chrome: FF5 is showing 55000 ops/sec
> while Ch14 is showing 1100 (see comparison table below in
> http://jsperf.com/typedarraysetvscreate/2 ).

It is almost certain that this could be optimized further and I've
asked the V8 team about this possibility. Add yourself to the CC: list
of http://crbug.com/84007 if you want to track the progress.

-Ken

philogb

unread,
Jun 17, 2011, 8:17:57 PM6/17/11
to WebGL Dev List
Great, thanks a lot for the explanation Ken,

Have a nice weekend,

On Jun 17, 3:47 pm, Kenneth Russell <k...@chromium.org> wrote:
> On Fri, Jun 17, 2011 at 1:44 PM, philogb <phil...@gmail.com> wrote:
> > Hi Ken,
>
> > Thanks for your reply.
>
> > I guess my question is, how come a linear operation in javascript code
> > (for-loop) roughly equivalent to the set operation is so fast compared
> > to the same constant time operation in JS (the use of the set method)
> > in V8?
>
> In both cases an element-by-element copy of the JavaScript array needs
> to be made. When doing this copy in JavaScript, the V8 engine gets to
> optimize the fetch of each JS array element and the store into the
> typed array. When calling the set() method, each JS array element is
> fetched using V8's C++ API -- seehttp://trac.webkit.org/browser/trunk/Source/WebCore/bindings/v8/custo...
> -- which is currently slow.
>
> > Also, I'm sure there should be more room for performance improvements
> > in the use of the set method in Chrome: FF5 is showing 55000 ops/sec
> > while Ch14 is showing 1100 (see comparison table below in
> >http://jsperf.com/typedarraysetvscreate/2).
>
> It is almost certain that this could be optimized further and I've
> asked the V8 team about this possibility. Add yourself to the CC: list
> ofhttp://crbug.com/84007if you want to track the progress.
>
> -Ken
>
>
>
> > Maybe I'm missing something?
>
> > PS: @Cedric Pinson: I'm not sure that is the best approach to be
> > taken, the experience in other browsers (Firefox for example) will be
> > downgraded. If you see for example FF5 statistics in the jsperf page,
> > you'll see that the set method is 5 times faster than a for-loop
> > assignment.
>
> > On Jun 17, 12:41 pm, Kenneth Russell <k...@chromium.org> wrote:
> >> What is your question specifically?
>
> >> In Chrome, yes, calling typed arrays' set() method with a JavaScript
> >> array as argument is slow. Some recent work has been done -- seehttp://crbug.com/84007--and some more is ongoing, but I am not sure

Robert Steckroth

unread,
Jun 17, 2011, 9:13:20 PM6/17/11
to webgl-d...@googlegroups.com
var buffer = new ArrayBuffer(16);
This looks like a viable solution -->

https://developer.mozilla.org/en/javascript_typed_arrays

Any positive feedback? If so, I would be willing to create a test for
it as well.


1 var int16View = new Int16Array(buffer);
2
3 for (var i=0; i<int16View.length; i++) {
4 console.log("Entry " + i + ": " + int16View[i]);
5 }

Here we create a 16-bit integer view that shares the same buffer as
the existing 32-bit view and we output all the values in the buffer as
16-bit integers. Now we get the output 0, 0, 2, 0, 4, 0, 6, 0.

You can go a step farther, though. Consider this:
1 int16View[0] = 32;
2 console.log("Entry 0 in the 32-bit array is now " + int32View[0]);

--
Bringing game to younix
Bust0ut Entertainment  ---
PureBreedDefense.com --> TheLinuxGame.com --> PBDefence.com
"Finding the exit without looking"

Reply all
Reply to author
Forward
0 new messages