2016-06-23 19 views
6

Nie mogę znaleźć jednoznacznej odpowiedzi w dowolnym miejscu.Web Worker 20x gorszy występ

Mam bardzo prosty POC, który oblicza tę samą funkcję w modzie synchronicznej i asynchronicznej.

Worker.js

onmessage = function(e) { 
    var s = new Date().getTime(); 
    i = 0; 
    var avg = Math.random(); 
    while (i < e.data){ 
    avg = (avg + Math.random())/2 ; 
    i++; 
    } 
    var d = new Date().getTime(); 
    console.log('Duration ' + (d - s)); 
    postMessage(avg); 
} 

Index.html

<script> 
var mw = new Worker("worker.js"); 

mw.onmessage = function(e) { 
    console.log('Worker says: ' + e.data); 
    }; 

function av (j){ 
    var s = new Date().getTime(); 
    i = 0; 
    var avg = Math.random(); 
    while (i < j){ 
    avg = (avg + Math.random())/2 ; 
    i++; 
    } 
    var d = new Date().getTime(); 
    console.log('Result is ' + avg); 
    console.log('Duration ' + (d - s)); 
} 



function runSync(){ 
    av(100000000); 
} 
function runAsync(){ 
    mw.postMessage(100000000); 
} 

</script> 

    <a href="#" onClick="runSync()" /> Run Sync </a> 

    <a href="#" onClick="runAsync()" /> Run Async </a> 

Na moim 4 rdzenia MacBook to generuje:

Result is 0.47398200501358567 
Duration 985 
Duration 23187 
Worker says: 0.7422913957976759 

Jak widać robotnika internetowej trwa 20x dłużej do procesu . Jakie jest tego wytłumaczenie? Inne powiązane posty sugerowały zbieranie śmieci i stertę, ale potem okazało się, że sprawcą jest problem z interfejsem API. Bardzo chcę zrozumieć, kim są i nie są pracownicy. Czy mają jakieś dziwne kary za wydajność, gdy uruchamia się garbage collector? Jeśli tak, jak zarządzać pamięcią w taki sposób, aby uniknąć takich wąskich gardeł?

+5

To może nie być ważne, ale zauważam, że funkcje nie są identyczne. Wersja robocza używa 'e.data', podczas gdy główny wątek ma jeden' ​​j'. Również dobrze byłoby wiedzieć, w jakiej przeglądarce to uruchomiłeś. –

+5

Używanie 'e.data' jest sprawcą, jeśli buforujesz je w zmiennej, działa tak samo szybko jak skrypt inlined (przynajmniej w Chrome). – robertklep

+0

@robertklep masz rację! Dlaczego powoduje to tyle kłopotów? Czy iteracja po zdarzeniu jakoś rośnie w stos? n.b. to działało w Chrome. – dzh

Odpowiedz

0

Nie są one dokładnie takie same funkcje, jesteś acessing e.data w pracownika, wich jej o wiele wolniej niż accesing buforowanych j bezpośrednio, czy to zmienić, powinny brać w tym samym czasie.