在上一篇“HTML5标准与性能之一:WebWorkers”中,我们了解了Web Workers为计算密集型的Web应用带来的优势。那这篇文章就为大家介绍另一个有助于性能提升的HTML5标准——Typed Array。
Typed Array
在JS语言中,数值只有一种称为Number的类型,而不像C语言或底层CPU指令那样区分是整型还是浮点型,是有符号的还是无符号的,是32位的还是64位的,因此如果用JS来实现32位整型的除法计算(结果仍是32位整型),就需要利用标准库函数Math.floor (x / y)
来模拟实现,可想而知性能会大打折扣。另外,JS不具备二进制格式数据的解析能力,必须利用一些非常规手段来实现,首先要把二进制数据作为文本读入(通过AJAX等),然后用String.prototype.charCodeAt(i)
来依次读取每个字节的数据,如果进一步需要解析各种不同类型的数据则难上加难。
Typed Array的提出主要是为了弥补JS处理二进制格式数据的不足,利用Typed Array你可以非常方便地操作二进制的数据(例如二进制的文件、网络数据等等),固定类型数值的计算加速,或者实现类似C的struct和union的功能。Typed Array最早作为WebGL标准的一部分,由Khronos标准组提出,后来又提入JavaScript语言标准EcmaScript中,现在大多数浏览器包括移动浏览器也都支持Typed Array。除WebGL,众多HTML5标准也都利用了Typed Array定义的接口,例如:Canvas 2D、File API、WebSocket API、Web Workers、XMLHttpRequest (AJAX)、Web Audio API、Media Source等等。
Typed Array主要由下面几个类构成:
ArrayBuffer
: 连续的内存缓冲区,用于实际储存各种类型的数组数据Typed Array View类:比如
Int32Array
、Uint8Array
、Float32Array
等,表示一个特定类型的数组DataView
: 工具类,提供getUint8、setFloat32等工具方法修改ArrayBuffer不同位置的数据值
每个Typed Array类的对象内部都指向一个ArrayBuffer
,多个Typed Array对象可以共享同一个ArrayBuffer
的缓冲区,我们下面来看一下Typed Array的基本用法:
// 创建一个8字节长的ArrayBuffer var b = new ArrayBuffer(8); // 创建v1指向b,32位整型,从0字节开始延伸到缓冲区结尾 var v1 = new Int32Array(b); // 创建v2指向b,8位无符号整型,从2字节开始延伸到缓冲区结尾 var v2 = new Uint8Array(b, 2); // 创建v3指向b,16位整型,从2字节开,长度为2 var v3 = new Int16Array(b, 2, 2);
以上三个变量在内存中的关系如下图:
var | index | |||||||
---|---|---|---|---|---|---|---|---|
bytes (not indexable) | ||||||||
b = | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
indices | ||||||||
v1 = | 0 | 1 | ||||||
v2 = | 0 | 1 | 2 | 3 | 4 | 5 | ||
v3 = | 0 | 1 |
Typed Array可以用来解析二进制数据、模拟C语言的struct/union结构等等,推荐大家参考这篇文章:Typed Arrays: Binary Data in the Browser。