Monday, May 20, 2024
25
rated 0 times [  29] [ 4]  / answers: 1 / hits: 5732  / 10 Years ago, sat, july 12, 2014, 12:00:00

I'm trying to improve the performance of a script when executed in a web worker. It's designed to parse large text files in the browser without crashing. Everything works pretty well, but I notice a severe difference in performance for large files when using a web worker.



So I conducted a simple experiment. I ran the script on the same input twice. The first run executed the script in the main thread of the page (no web workers). Naturally, this causes the page to freeze and become unresponsive. For the second run, I executed the script in a web worker.





For small files in this experiment (< ~100 MB), the performance difference is negligible. However, on large files, parsing takes about 20x longer in the worker thread:



Performance



The blue line is expected. It should only take about 11 seconds to parse the file, and the performance is fairly steady:



Performance



The red line is the performance inside the web worker. It is much more surprising:



Performance



The jagged line for the first 30 seconds is normal (the jag is caused by the slight delay in sending the results to the main thread after every chunk of the file is parsed). However, parsing slows down rather abruptly at 30 seconds. (Note that I'm only ever using a single web worker for the job; never more than one worker thread at a time.)



I've confirmed that the delay is not in sending the results to the main thread with postMessage(). The slowdown is in the tight loop of the parser, which is entirely synchronous. For reasons I can't explain, that loop is drastically slowed down and it gets slower with time after 30 seconds.



But this only happens in a web worker. Running the same code in the main thread, as you've seen above, runs very smoothly and quickly.



Why is this happening? What can I do to improve performance? (I don't expect anyone to fully understand all 1,200+ lines of code in that file. If you do, that's awesome, but I get the feeling this is more related to web workers than my code, since it runs fine in the main thread.)



System: I'm running Chrome 35 on Mac OS 10.9.4 with 16 GB memory; quad-core 2.7 GHz Intel Core i7 with 256 KB L2 cache (per core) and L3 Cache of 6 MB. The file chunks are about 10 MB in size.



Update: Just tried it on Firefox 30 and it did not experience the same slowdown in a worker thread (but it was slower than Chrome when run in the main thread). However, trying the same experiment with an even larger file (about 1 GB) yielded significant slowdown after about 35-40 seconds (it seems).


More From » multithreading

 Answers
2

Tyler Ault suggested one possibility on Google+ that turned out to be very helpful.



He speculated that using FileReaderSync in the worker thread (instead of the plain ol' async FileReader) was not providing an opportunity for garbage collection to happen.



Changing the worker thread to use FileReader asynchronously (which intuitively seems like a performance step backwards) accelerated the process back up to just 37 seconds, right where I would expect it to be.



I haven't heard back from Tyler yet and I'm not entirely sure I understand why garbage collection would be the culprit, but something about FileReaderSync was drastically slowing down the code.


[#43934] Friday, July 11, 2014, 10 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
micayla

Total Points: 148
Total Questions: 92
Total Answers: 109

Location: Aruba
Member since Sat, Oct 2, 2021
3 Years ago
micayla questions
Fri, Dec 24, 21, 00:00, 2 Years ago
Thu, Apr 16, 20, 00:00, 4 Years ago
Thu, Nov 14, 19, 00:00, 5 Years ago
;