HTML5标准与性能之二:Typed Array

在上一篇“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 2DFile APIWebSocket APIWeb WorkersXMLHttpRequest (AJAX)Web Audio APIMedia Source等等。

Typed Array主要由下面几个类构成:

  • ArrayBuffer: 连续的内存缓冲区,用于实际储存各种类型的数组数据

  • Typed Array View类:比如Int32ArrayUint8ArrayFloat32Array等,表示一个特定类型的数组

  • 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);

以上三个变量在内存中的关系如下图:

varindex
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

参考

  1. Typed Arrays: Binary Data in the Browser

  2. Reading files in JavaScript using the File APIs

  3. Typed Array Specification

Para obtener más información sobre las optimizaciones del compilador, consulte el aviso sobre la optimización.