大きな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);
転送可能なオブジェクトを使用しても、既存のJson配列から最初からビルドする必要がある場合は役に立ちません(これはクローン作成に非常に近いです...)
Jsonデータはどこから来ていますか?ワーカースレッドですべてのハードワークを維持するための1つの可能な方法は、XmlHttpRequestを使用してデータをフェッチし、変換してUIスレッドに送信することです。このように、クローン作成の高コストはワーカースレッドで発生し、UIスレッドの場合と同じ時間がかかりますが、アプリをブロックすることはありません。
「転送可能なオブジェクト」を使用していない間、これはあなたの問題を解決するかもしれません。
データ表現を最適化することもできます。例えば。あなたの例では、パック/アンパックに約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');
わかりました、私はこれをしました、それがそれをするのに良いか悪いか、理想的か最悪の方法かどうかわかりません。やったよ。ワーカーファイル内
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オブジェクトを送信し、転送することができます。