作者:Lin Clark
译者:Cody Chan
原帖链接:A cartoon intro to ArrayBuffers and SharedArrayBuffers
这是图解 SharedArrayBuffers 系列的第二篇:
图解 ArrayBuffers 和 SharedArrayBuffers
上一篇文章中,我诠释了 JavaScript 这类自动治理内存的言语是怎样处置惩罚内存的,一样也诠释了相似 C 言语这类手动治理内存的言语
为何这关于我们议论的 ArrayBuffers 和 SharedArrayBuffers 云云主要?
由于纵然你运用的是 JavaScript 这类自动治理内存的言语,ArrayBuffers 也供应了一种手动处置惩罚数据的门路
为何你会有如许的需求呢?
正如上篇文章所说,这里有个衡量,自动治理内存对开发者是友爱的,然则这会增添机械累赘,以至会有机能题目
比方,JS 里建立一个变量,引擎会去猜想变量的范例以及内存里怎样示意。由于有了范例猜想,JS 引擎平常会比实在须要预留更多的空间。依据变量差别,内存分派可以会是实在需求的 2-8 倍,这致使了内存糟蹋
而且,某些建立和运用 JS 对象的场景会让渣滓接纳变得很难题。假如你是手动保护的内存,可以依据实际运用需求来决议分派和开释内存的战略
许多时刻,这不是什么大不了的事。大多数场景并不会对机能请求那末刻薄,反而更多地忧郁治理内存的贫苦。而且平常状况下,手动治理内存可以更慢
然则关于底层须要极致优化的场景,ArrayBuffers 和 SharedArrayBuffers 为你供应了可以
ArrayBuffer 是怎样事情的
ArrayBuffer 跟别的 JavaScript 数组差不多,然则不是一切 JavaScript 范例都可以放进去,比方对象、字符串。你唯一可以放进去的只要字节(可以用数字示意)
须要廓清的一点是,你事实上不是直接把这个字节到 ArrayBuffer 里就好了,ArrayBuffer 并不晓得字节有多长,该用若干位去存
ArrayBuffer 仅仅是一个个 0/1 构成的串,它不晓得第一个元素和第二个元素的支解点
为了供应必要的上下文信息,把 ArrayBuffer 分块,我们须要把它包裹到视图里,这些数据的视图可以经由历程带范例的数组增加,已支撑许多种范例的数组了
比方,你可以用一个 Int8 范例的数组把 0/1 串支解成 8 位一组的序列
或许你可以用一个无符的 Int16 范例数组,把它支解成 16 位一组的序列,可以把它看成无符整型处置惩罚
以至你可以在统一个基本 buffer 上同时处置惩罚多种视图,差别视图在雷同支配下会返回差别的效果
比方,假如我们从某个 ArrayBuffer 的 Int8 视图获得第 0 和第 1 个元素的值,在 Uint16 视图下,第 0 个元素与其有雷同二进制位值,然则获得的值也会不一样
这类体式格局下,ArrayBuffer 几乎是饰演原始内存角色了,它模仿内存的种种跟 C 言语里相似的支配
你可以疑惑了,为何不让开发者直接支配内存而是采纳这个笼统层。由于直接支配内存会有平安风险,这个今后的文章会讲
什么是 SharedArrayBuffer
为了说邃晓 SharedArrayBuffers,我须要轻微诠释下并行运转代码和 JavaScript 的关联
为了更快运转代码或许更更快相运用户事宜,你可以会让代码并行运转,为了做到这点,你须要支解事情
一个典范的运用中,一切的事情都由一个零丁的主线程处置惩罚,这点我之前提到过……这个主线程就像一个全栈工程师,掌管着 JavaScript、DOM 和 视图
任何可以从主线程负载削减事情的要领都对代码运转效力有协助,某些状况下,ArrayBuffers 可以削减大批应当由主线程做的事情
然则也有些时刻削减主线程负载是远远不够的,偶然你须要支援,你须要支解你的使命
大多数言语里,这类支解事情的要领可以运用多线程完成,这就像许多人同时在一个项目里事情。假如你可以完美地把使命支解为多个自力的部份,你可以分给差别的线程,然后,这些线程就同时种种自力实行这些使命
在 JavaScript 里,你可以借助 web worker 做这类事,这些 web workers 跟别的言语的线程照样有些区分的,默许它们不能同享内存
这意味着假如你想分派你的使命给别的线程,你须要完整把使命复制过去,这可以经由历程 postMessage 完成
postMessage 把你传给它的任何对象都序列化,发送到别的 web worker,然后那里吸收后反序列化并放进内存
这个历程是异常慢的
某些范例数据(如 ArrayBuffers)你可以经由历程挪动内存的体式格局完成,这意味着把某个特定地区的内存移过去后别的 web worker 就可以直接接见了
然则,之前的 web worker 就无法接见了
关于某些场景这是有用的,然则也有许多场景对机能请求高,你只能运用同享的内存
而这就是 SharedArrayBuffers 为你供应的
有了 SharedArrayBuffer 后,多个 web worker 就可以同时读写统一块内存了
你再也不须要 postMessage 伴偶然延的通讯了,多个 web worker 对数据接见都没偶然延了
固然,这类同时接见也有风险,会发生合作前提
这个下一篇文章会细说
SharedArrayBuffers 支撑状况
一切主流浏览器都将会支撑 SharedArrayBuffers
Safari 10.1 已支撑了,Firefox 和 Chrome 也会很快支撑并宣布,Edge 会在他们秋季 Windows 更新的时刻宣布
纵然一切主流浏览器都支撑了,我们也不愿望开发者直接运用它们,事实上,我们是阻挡的。你应当只运用更高等的封装好的笼统层接口
我们期盼的是 JavaScript 库开发者可以供应更简朴平安的要领来运用 SharedArrayBuffers
而且,一旦 SharedArrayBuffers 内置到平台中,WebAssembly 可以经由历程它完成多线程,到那时刻你就可以运用相似 Rust 的多线程言语轻松玩转多线程了
下一篇文章我们会引见一个为防止合作前提的库供应基本支配的东西(Atomics)