Próbuję poprawić wydajność skryptu po jego uruchomieniu w usłudze WWW. Jest przeznaczony do parsowania dużych plików tekstowych w przeglądarce bez awarii. Wszystko działa całkiem nieźle, ale zauważam poważną różnicę w wydajności dużych plików podczas korzystania z web-pracownika.Dlaczego wydajność pracownika WWW gwałtownie spada po 30 sekundach?
Przeprowadziłem więc prosty eksperyment. Dwa razy uruchomiłem skrypt na tym samym wejściu. Pierwsze uruchomienie wykonało skrypt w głównym wątku strony (brak pracowników WWW). Naturalnie powoduje to zamrożenie strony i przestaje reagować. W drugim uruchomieniu skrypt wykonałem w usłudze WWW.
Dla małych plików w tym eksperymencie (< ~ 100 MB), różnica wydajności jest znikomy. Jednak na dużych plikach, parsowanie trwa około 20x dłużej w wątku roboczego: Oczekuje
Niebieska Linia. Należy jedynie około 11 sekund, aby przetworzyć plik, a wydajność jest dość stabilny:
Czerwona linia jest wykonanie wewnątrz pracownika internetowej. Jest o wiele bardziej zaskakujące:
poszarpanej linii przez pierwsze 30 sekund jest normalne (Iglica jest spowodowany niewielkim opóźnieniem wysyłania wyników do głównego wątku po każdym fragmencie pliku jest analizowany). Jednak parsowanie spowalnia raczej gwałtownie po 30 sekundach. (Zauważ, że do pracy używam tylko jednego pracownika WWW, nigdy więcej niż jednego wątku roboczego na raz.)
Potwierdziłem, że opóźnienie wynosi , a nie w wysyłaniu wyników do głównego wątku wątek z postMessage()
. Spowolnienie jest w the tight loop parsera, który jest całkowicie synchroniczny. Z powodów, których nie potrafię wyjaśnić, pętla jest drastycznie spowolniona, a po 30 sekundach staje się wolniejsza.
Ale dzieje się tak tylko w przeglądarce internetowej. Uruchamianie tego samego kodu w głównym wątku, jak widać powyżej, przebiega bardzo sprawnie i szybko.
Dlaczego tak się dzieje? Co mogę zrobić, aby poprawić wydajność? (Nie oczekuję, że ktokolwiek w pełni zrozumie wszystkie 1200 wierszy kodu w tym pliku. Jeśli to zrobisz, to jest niesamowite, ale mam wrażenie, że jest to bardziej związane z pracownikami sieciowymi niż z moim kodem, ponieważ działa dobrze w głównym wątek.)
System: używam Chrome 35 na Mac OS 10.9.4 z 16 GB pamięci; czterordzeniowy procesor Intel Core i7 2,7 GHz z pamięcią podręczną L2 o pojemności 256 KB (na rdzeń) i pamięcią podręczną L3 o pojemności 6 MB. Rozmiar pliku wynosi około 10 MB.
Aktualizacja: prostu próbowałem go na Firefox 30 i to zrobił nie doświadczenie tego samego spowolnienie w wątku roboczego (ale to był wolniejszy niż Chrome po uruchomieniu w głównym wątku). Jednak próba wykonania tego samego eksperymentu z jeszcze większym plikiem (około 1 GB) przyniosła znaczące spowolnienie po około 35-40 sekundach (wydaje się).
Widzę to samo z prostą pętlą i = i + 1, drukującą komunikat co 1 milion iteracji. Spowolnienie rozpoczyna się po około 20 sekundach w przeglądarce Chrome i 12 sekundach w Firefoksie. Co to jest? –