2012-07-06 69 views
27

在大型JSON对象上使用worker.postMessage时,HTML 5 Web Worker非常慢。 我想弄清楚如何将JSON对象转移到网络工作人员 - 在Chrome中使用“可转移对象”类型,以提高此速度。Web Workers - 用于JSON的可转移对象

这里是我指的是,似乎应该加快这颇有几分: http://updates.html5rocks.com/2011/12/Transferable-Objects-Lightning-Fast

我无法找到的一个很好的例子(我不相信,我想使用ArrayBuffer)。任何帮助,将不胜感激。虽然没有使用“转换对象”

worker = new Worker('workers.js'); 

var large_json = {}; 
for(var i = 0; i < 20000; ++i){ 
    large_json[i] = i; 
    large_json["test" + i] = "string"; 
}; 

//How to make this call to use Transfer Objects? Takes approx 2 seconds to serialize this for me currently. 
worker.webkitPostMessage(large_json); 
+4

这是工作人员以他们目前的幌子倒下的地方,因为他们与父母的脚本没有任何关系,因此任何你想传递给他们的东西都会涉及到一个令人讨厌的复制操作。 Webkit的“通过引用”方式绝对是一种可行的方式。除此之外,还有两点让我感到震惊:如果你延迟了2秒,这可能会损害您使用网络工作者可能获得的任何节省,所以您最好避免使用它们,从而也避免序列化。 2)如何处理这种大小的数据的Web SQL?更快? – Utkanos 2012-07-06 16:19:00

+0

我基本上需要操纵JSON并将其传回,所以我不相信Web SQL会起作用。在我的正常情况下,我不会传输这么大的JSON对象,但我用它来进行测试/演示。我相信*从我一直在读的内容可以看出,Transferable Objects可以使它成为一个非常快速的参考传递操作,从而实现了非常及时的传输,远远低于目前的2秒。但是,我无法找到如何真正做到这一点的任何示例。 – kclem06 2012-07-06 16:28:47

+0

“像File,Blob,ArrayBuffer和JSON对象这样的复杂类型。” - 显示它应该受支持:https://developer.mozilla.org/en/Using_web_workers – kclem06 2012-07-06 20:53:07

回答

0

,但是这可能会解决你的问题:

我想象这样的事情。

您也可以尝试优化您的数据表示。 例如你的榜样采取〜1350ms收拾/解压缩,我(谷歌浏览器19),而是执行以下代码〜25倍的速度(50毫秒):

console.time('json'); 
var a = [], test = []; 
for(var i = 0; i < 20000; ++i){ 
    a.push(i); 
    test.push("string"); 
}; 
var large_json = { 
    a: a.join(','), 
    test: test.join(',') 
}; 
large_json = JSON.parse(JSON.stringify(large_json)); 
large_json.a = large_json.a.split(","); 
large_json.test = large_json.test.split(","); 
console.timeEnd('json'); 
0

好吧我这样做,我不知道,如果它是好还是坏,理想或最差的方式来做到这一点。我刚刚做完。 在HTML文件中

function str2ab(str) { 
    var buf = new ArrayBuffer(str.length*2); // 2 bytes for each char 
    var bufView = new Uint16Array(buf); 
    for (var i=0, strLen=str.length; i<strLen; i++) { 
    bufView[i] = str.charCodeAt(i); 
    } 
    return buf; 
} 
function stop() { 
var obj = {'cmd': 'stop', 'msg': 'Bye'}; 
var str= JSON.stringify(obj); 
var arbfr = str2ab(obj); 
worker.postMessage(arbfr,[arbfr]); 
} 

工人文件

var data = e.data; 
var string = String.fromCharCode.apply(null, new Uint16Array(data)); 
var objnow = JSON.parse(string); 

而现在它的作品,我能够发送JSON对象,转让。

1

使用,如果你要从头开始从现有的JSON数组建立它转让对象将不会帮助(这是非常接近的克隆...)

哪里JSON数据从何而来?保持工作线程所有工作的一种可能方式是让它使用XmlHttpRequest获取数据,将其转换并发送到UI线程。这样,克隆的高成本就发生在工作者线程上,并且与UI线程中的时间相同,它不会阻止您的应用程序。

+0

I/O请求不会阻止....包括Ajax – dman 2016-11-06 02:53:19

+1

的确如此?但这不是我的观点 – AlexG 2016-11-06 20:23:37