JavaScript 数组不是连续(contiguous)的,其实现类似哈希映射(hash-maps)或字典(dictionaries)。觉得这有点像是一门 B 级语言,数组实现根本不恰当。
工具/原料
- JavaScript、电脑操作系统
方法/步骤
- 1
为什么说 JavaScript 数组不是真正的数组
数组是一串连续的内存位置,用来保存某些值。注意重点,“连续”(continuous,或 contiguous),这很重要。
- 2
上图展示了数组在内存中存储方式。这个数组保存了 4 个元素,每个元素 4 字节。加起来总共占用了 16 字节的内存区。
假设声明了 tinyInt arr[4];,分配到的内存区的地址从 1201 开始。一旦需要读取 arr[2],只需要通过数学计算拿到 arr[2] 的地址即可。计算 1201 + (2 X 4),直接从 1209 开始读取即可。
- 3
JavaScript 中的数据是哈希映射,可以使用不同的数据结构来实现,如链表。所以,如果在 JavaScript 中声明一个数组 var arr = new Array(4),计算机将生成类似上图的结构。如果程序需要读取 arr[2],则需要从 1201 开始遍历寻址。
以上急速 JavaScript 数组与真实数组的不同之处。显而易见,数学计算比遍历链表快。就长数组而言,情况尤其如此。
JavaScript 数组的进化
JavaScript 这门语言也进化了不少。从 V8、SpiderMonkey 到 TC39 和与日俱增的 Web 用户,巨大的努力已经使 JavaScript 成为世界级必需品。一旦有了庞大的用户基础,性能提升自然是硬需求。
现代 JavaScript 引擎是会给数组分配连续内存的 —— 如果数组是同质的(所有元素类型相同)。优秀的程序员总会保证数组同质,以便 JIT(即时编译器)能够使用 c 编译器式的计算方法读取元素。
想要在某个同质数组中插入一个其他类型的元素,JIT 将解构整个数组,并按照旧有的方式重新创建。
如果代码写得不太糟,JavaScript Array 对象在幕后依然保持着真正的数组形式,这对现代 JS 开发者来说极为重要。
数组跟随 ES2015/ES6 有了更多的演进。TC39 决定引入类型化数组(Typed Arrays),于是我们就有了 ArrayBuffer。
ArrayBuffer 提供一块连续内存供随意操作。直接操作内存还是太复杂、偏底层。于是便有了处理 ArrayBuffer 的视图(View)。目前已有一些可用视图,未来还会有更多加入。
- 4
了解更多关于类型化数组(Typed Arrays)的知识,请访问 MDN 文档。
高性能、高效率的类型化数组在 WebGL 之后被引入。WebGL 工作者遇到了极大的性能问题,即如何高效处理二进制数据。可以使用 SharedArrayBuffer 在多个 Web Worker 进程之间共享数据提升性能。
从简单的哈希映射到现在的 SharedArrayBuffer
旧式数组 vs 类型化数组:性能
前面已经讨论了 JavaScript 数组的演进,现在来测试现代数组到底能带来多大收益。
- 5
旧式数组和 ArrayBuffer 的性能不相上下,现代编译器已经智能化,能够将元素类型相同的传统数组在内部转换成内存连续的数组。第一个例子正是如此。尽管使用了 new Array(LIMIT),数组实际依然以现代数组形式存在。
接着修改第一例子,将数组改成异构型(元素类型不完全一致)的,来看看是否存在性能差异。
- 6
改变发生在第 3 行,添加一条语句,将数组变为异构类型。其余代码保持不变。性能差异表现出来了,慢了 22 倍。
旧式数组:读取
- 7
类型化数组的引入是 JavaScript 发展历程中的一大步。Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,这些是类型化数组视图,使用原生字节序(与本机相同)。我们还可以使用 DataView 创建自定义视图窗口。希望未来会有更多帮助我们轻松操作 ArrayBuffer 的 DataView 库。
JavaScript 数组的演进非常 nice。现在它们速度快、效率高、健壮,在内存分配时也足够智能。
来源:百闻(微信/QQ号:9397569),转载请保留出处和链接!
本文链接:https://www.ibaiwen.com/web/244591.html
- 上一篇: Windows10自带防火墙在哪里设置 如何关闭与开启
- 下一篇: 用Excel怎么制作出差报销单
- 热门文章
-
WB蒙特利尔(WB Montreal)——欧美十大最差视频游戏开发商
迅猛龙(Velociraptor)——欧美史前十大死亡动物
什么是果酱猫(What Marmalade Cats)?
神奇蜘蛛侠2(The Amazing Spider-Man 2)——欧美最佳蜘蛛侠电影
希瑟(Heather)——欧美十大最佳柯南灰歌
二人梭哈
faceu激萌怎么把瘦脸开到最大
奥兹奥斯本(Ozzy Osbourne)——欧美十大高估歌手
什么是小脑前下动脉(Anterior Inferior Cerebellar Artery)?
我应该知道康涅狄格州的什么(What Should I Know About Connecticut)?
- 热评文章
- 最新评论
-
- 最近访客
-
- 站点信息
-
- 文章总数:200248
- 页面总数:9
- 分类总数:1
- 标签总数:0
- 评论总数:0
- 浏览总数:497