javascript - 为什么 Web Worker 性能在 30 秒后急剧下降?

标签 javascript multithreading performance google-chrome web-worker

我正在尝试提高在网络 worker 中执行脚本时的性能。它旨在解析浏览器中的大型文本文件而不会崩溃。一切都运行得很好,但我注意到使用网络 worker 时大文件的性能存在严重差异。

所以我做了一个简单的实验。我在同一输入上运行脚本两次。第一次运行在页面的主线程中执行脚本(没有网络 worker )。当然,这会导致页面卡住并变得无响应。对于第二次运行,我在 Web Worker 中执行了脚本。

对于本实验中的小文件 (< ~100 MB),性能差异可以忽略不计。但是,对于大文件,工作线程中的解析时间大约要长 20 倍:

Performance of both scenarios on same graph

蓝线是预期的。解析文件只需要大约11秒,并且性能相当稳定:

Performance of script without web worker

红线是网络 worker 内部的性能。更令人惊讶的是:

Performance of script in web worker

前 30 秒的锯齿线是正常的(锯齿是由于解析文件的每个 block 后将结果发送到主线程的轻微延迟造成的)。然而,解析速度在 30 秒时突然减慢。 (请注意,我只使用一个 Web Worker 来完成这项工作;一次不会使用多个工作线程。)

我已经确认,使用 postMessage() 将结果发送到主线程时没有出现延迟。放缓发生在the tight loop解析器的,它是完全同步的。由于我无法解释的原因,该循环速度大大减慢,并且在 30 秒后随着时间的推移变得更慢。

但这仅发生在网络 worker 中。正如您在上面所看到的,在主线程中运行相同的代码运行得非常流畅和快速。

为什么会发生这种情况?我可以做什么来提高性能? (我不希望任何人完全理解该文件中的所有 1,200 多行代码。如果您这样做,那就太棒了,但我感觉这与网络工作人员比我的代码更相关,因为它在主程序中运行良好线程。)

系统:我在 Mac OS 10.9.4 上运行 Chrome 35,内存为 16 GB;四核 2.7 GHz Intel Core i7,具有 256 KB L2 高速缓存(每核)和 6 MB L3 高速缓存。文件 block 的大小约为 10 MB。

更新:刚刚在 Firefox 30 上尝试过,它没有在工作线程中经历同样的减速(但在主线程中运行时比 Chrome 慢) )。然而,尝试使用更大的文件(大约 1 GB)进行相同的实验在大约 35-40 秒后(看起来)出现了显着的减速。

最佳答案

Tyler Ault suggested one possibility on Google+事实证明这非常有帮助。

他推测在工作线程中使用FileReaderSync(而不是普通的异步FileReader)并没有为垃圾收集提供机会。

将工作线程更改为异步使用 FileReader(直观上这似乎是一个性能倒退倒退),将进程加速到仅 37 秒,正是我所期望的就这样吧。

我还没有收到 Tyler 的回复,我也不完全确定我理解为什么垃圾收集会成为罪魁祸首,但有关 FileReaderSync 的速度急剧变慢下代码。

关于javascript - 为什么 Web Worker 性能在 30 秒后急剧下降?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24708649/

相关文章:

javascript - 如何使用 Vuejs 在 html 中显示 mysql blob 图像?

c++ - 读锁在 C++ 中有什么作用?

java - 为什么这个 LinkedList 被锁定在一个空的 while 循环中?

Java:基于时间的线程锁定

sql - Postgres - 使用 where 子句的慢速简单连接

javascript - 同一页面上的多个滚动条

javascript - 我们如何为 3 个函数重用 jQuery ajax 方法?

javascript - node.js socket.io 计时器 - 单例模式?

sql-server - 为什么我的主键会减慢我的查询速度?

javascript - 上传后显示图像预览