web-dev-qa-db-ja.com

Webワーカー-JSON用の転送可能なオブジェクト

大きなJSONオブジェクトでworker.postMessageを使用すると、HTML 5Webワーカーは非常に遅くなります。この速度を上げるために、Chromeで「転送可能なオブジェクト」タイプを使用してJSONオブジェクトをWebワーカーに転送する方法を理解しようとしています。

これが私が言及しているものであり、これをかなりスピードアップするはずです: 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);
30
kclem06

転送可能なオブジェクトを使用しても、既存のJson配列から最初からビルドする必要がある場合は役に立ちません(これはクローン作成に非常に近いです...)

Jsonデータはどこから来ていますか?ワーカースレッドですべてのハードワークを維持するための1つの可能な方法は、XmlHttpRequestを使用してデータをフェッチし、変換してUIスレッドに送信することです。このように、クローン作成の高コストはワーカースレッドで発生し、UIスレッドの場合と同じ時間がかかりますが、アプリをブロックすることはありません。

2
AlexG

「転送可能なオブジェクト」を使用していない間、これはあなたの問題を解決するかもしれません。

データ表現を最適化することもできます。例えば。あなたの例では、パック/アンパックに約1350ミリ秒かかります(Google Chrome 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
kirilloid

わかりました、私はこれをしました、それがそれをするのに良いか悪いか、理想的か最悪の方法かどうかわかりません。やったよ。ワーカーファイル内

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

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]);
}

そして今それは動作します私はjsonオブジェクトを送信し、転送することができます。

0
Muhammad Umer