2012-07-06 11 views
27

HTML 5 Los trabajadores web son muy lentos al usar worker.postMessage en un objeto JSON grande. Estoy intentando averiguar cómo transferir un objeto JSON a un trabajador web, utilizando los tipos de objetos transferibles en Chrome, para aumentar la velocidad de este.Web Workers - Objetos transferibles para JSON

Esto es lo que me refiero, y parece que debería acelerar esto un poco: http://updates.html5rocks.com/2011/12/Transferable-Objects-Lightning-Fast

estoy teniendo problemas para encontrar un buen ejemplo de esto (y no creo que quiero usa un ArrayBuffer). Cualquier ayuda sería apreciada.

estoy imaginando algo como esto:

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

Aquí es donde los trabajadores, en su forma actual, se caen, ya que no tienen conexión con el script principal, por lo que cualquier cosa que quiera pasarles implica una tediosa operación de copia. El enfoque de "paso por referencia" de Webkit es definitivamente el camino a seguir. Aparte de eso, me llaman la atención dos puntos: si te encuentras con una demora de 2 segundos, eso probablemente frustra cualquier ahorro que de otro modo hubieras podido obtener al usar trabajadores web, así que también podrías evitarlos y, por lo tanto, también evitar el publicación por entregas. 2) ¿Qué tal web SQL para datos de este tamaño, más rápido? – Utkanos

+0

Básicamente necesito manipular el JSON y transferirlo de vuelta, así que no creo que web SQL funcione. En mis casos normales, no estaría transfiriendo este gran objeto JSON, pero lo usé para propósitos de prueba/demostración. Creo * por lo que he estado leyendo que los Objetos transferibles lo convertirían en una operación de paso a paso muy rápida, lo que da como resultado una transferencia extremadamente puntual, muy por debajo de los 2 segundos actuales. Sin embargo, no puedo encontrar ningún ejemplo de cómo hacerlo. – kclem06

+0

"tipos complejos como archivos, Blob, ArrayBuffer y objetos JSON." - Parece que debe ser compatible: https://developer.mozilla.org/en/Using_web_workers – kclem06

Respuesta

0

Aunque no usar los objetos mobiliarios '', pero esto puede resolver su problema.

Puede tratar de optimizar su representación de datos también. P. ej. su ejemplo toma ~ 1350ms para empacar/desempacar para mí (Google Chrome 19), pero el siguiente código se ejecuta ~ 25 veces más rápido (50ms):

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

Ok lo hice yo no sé si es bueno o malo , ideal o peor forma de hacerlo. Solo lo hice. en el expediente del trabajador

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

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

Y ahora funciona soy capaz de enviar un objeto JSON, transferencia.

1

El uso de un objeto de mobiliario no ayudará si usted tiene que construir desde cero a partir de una matriz JSON existente (Eso es muy cerca de la clonación ...)

dónde viene el datos JSON viene? Una forma posible de mantener todo el trabajo duro en el hilo de trabajo es hacer que recupere los datos usando XmlHttpRequest, transformarlo y enviarlo al hilo de UI. De esta forma, el alto costo de la clonación se produce en el hilo del trabajador y, aunque tardará el mismo tiempo que en el hilo de la interfaz de usuario, no bloqueará su aplicación.

+0

Las solicitudes de E/S no se bloquean ... incluso Ajax – dman

+1

¿Efectivamente? Sin embargo, ese no era mi punto – AlexG