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ł?
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ś. –
Używanie 'e.data' jest sprawcą, jeśli buforujesz je w zmiennej, działa tak samo szybko jak skrypt inlined (przynajmniej w Chrome). – robertklep
@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