Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在Blob和ArrayBuffers之间转换而不复制?_Javascript_Performance_Arraybuffer - Fatal编程技术网

Javascript 在Blob和ArrayBuffers之间转换而不复制?

Javascript 在Blob和ArrayBuffers之间转换而不复制?,javascript,performance,arraybuffer,Javascript,Performance,Arraybuffer,我在Javascript中的ArrayBuffers和Blob之间转换的文档中找不到任何性能信息。我认为标准方法是: const blob = new Blob([arrayBuffer]) 及 请注意,我只关心内存中的blob,而不是基于文件的blob(因此不涉及I/O时间)。我在codepen中进行了一些计时: 这表明这两个操作都会根据ArrayBuffer的大小在时间上进行缩放,因此它们很可能是在复制数据。 事实上,如果我的计时代码准确的话,仅仅创建一个新的响应(blob)对于一个更大的

我在Javascript中的ArrayBuffers和Blob之间转换的文档中找不到任何性能信息。我认为标准方法是:

const blob = new Blob([arrayBuffer])

请注意,我只关心内存中的blob,而不是基于文件的blob(因此不涉及I/O时间)。我在codepen中进行了一些计时: 这表明这两个操作都会根据ArrayBuffer的大小在时间上进行缩放,因此它们很可能是在复制数据。 事实上,如果我的计时代码准确的话,仅仅创建一个
新的响应(blob)
对于一个更大的blob需要更长的时间。另外,新的
Blob.arrayBuffer()
函数也似乎是O(n),尽管它比
响应方式
快。但在2020年浏览器还没有很好的支持


所以我的问题是:是否有关于这些操作预期性能的权威文件?我只是用错了吗?有没有更快(固定时间、零拷贝)的方法?

冒着回答老问题的风险,对后代来说——您要查找的权威文档将分别是
Blob
ArrayBuffer
的[相关章节]和规范

就我所能确定的,两个规范都没有为任何一类对象指定特定的分配方案;虽然ECMAScript对
ArrayBuffer
的规范似乎更能暗示特定的数据分配机制,但这只是在规范本身的范围内——我找不到类似“必须在堆上分配数据”这样的内容;而
Blob
的规范在包含“Blob”的数据的实际分配位置和方式方面故意更加抽象和模糊

在这些规范的指导下,大多数用户代理都会在堆上天真地分配相应的
ArrayBuffer
length的数据,而构造的blob对象可以由内存映射文件有效地支持(例如,在
File
blob的情况下)这基本上会使它们在某些操作系统上得到页面文件的支持——这意味着在需要之前根本不会保留RAM(对于blob上的某些操作,比如将其转换为
ArrayBuffer

因此,从
Blob
ArrayBuffer
的转换虽然在技术上没有指定为
O(n)
,但在大多数用户代理中也是如此,因为后者有助于实际的即时读写数据访问(通过元素索引等),而
Blob
本身不允许任何即时数据访问

现在,我说的是“大多数用户代理”,因为从技术上讲,您可以设计一个非常复杂的数据访问机制,具有写时复制语义,在从
Blob
获取
ArrayBuffer
时不分配数据(通过您在问题中描述的任何方法或更现代的API,例如)在需要读取和/或修改相应数据之前

换句话说,您的所有基准测试只涉及具体的实现(阅读您尝试过的用户代理),这些实现可以自由地实现任何一个类以及与之相关的操作,但是只要它们不违反相应的规范,它们看起来都是合适的

然而,如果有足够多的人开始采用前后激进的blob转换,那么没有任何东西可以阻止像Mozilla或Google这样的供应商将其实现优化为上面描述的(写时复制),例如,这可能会或可能不会使它们变成
O(log(n))
操作。毕竟,JavaScript在很长一段时间内被称为“解释型”语言——但今天称之为解释型语言有点用词不当,因为Chrome的V8和Firefox的SpiderMonkey以优化的名义从中编译本机代码。而且,他们也可以自由地这样做——没有适用的语言规范或相关环境要求它“被解释”。Blob和数组缓冲区也是如此


不幸的是,在实践中,这意味着我们必须接受使用blob和数组缓冲区的程序的实际运行情况——通常,当您需要对blob做一些有用的事情时,这会产生真正的
O(n)
成本。

冒着回答旧问题的风险,对于后代——您正在寻找的权威文档将分别是
Blob
ArrayBuffer
的[相关章节]和规范

就我所能确定的,两个规范都没有为任何一类对象指定特定的分配方案;虽然ECMAScript对
ArrayBuffer
的规范似乎更能暗示特定的数据分配机制,但这只是在规范本身的范围内——我找不到类似“必须在堆上分配数据”这样的内容;而
Blob
的规范在包含“Blob”的数据的实际分配位置和方式方面故意更加抽象和模糊

在这些规范的指导下,大多数用户代理都会在堆上天真地分配相应的
ArrayBuffer
length的数据,而构造的blob对象可以由内存映射文件有效地支持(例如,在
File
blob的情况下)这基本上会使它们在某些操作系统上得到页面文件的支持——这意味着在需要之前根本不会保留RAM(对于blob上的某些操作,比如将其转换为
ArrayBuffer

因此,从
Blob
ArrayBuffer
的转换,虽然技术上没有指定为
O(n)
,但在大多数用户代理中都是如此,因为后者有助于实际的即时读写数据访问(通过元素索引等),而
const resp = new Response(blob)
const ab = await resp.arrayBuffer()