jjzjj

javascript - WebWorkers 的执行似乎比主线程慢得多

coder 2024-07-25 原文

我一直致力于优化一些长时间运行的 JavaScript,并尝试实现 WebWorkers。

我有一组独立的任务要计算。在我的初始测试中,有 80 个任务,在主线程上用了 250 毫秒完成。我认为我可以将任务分配给一些网络 worker ,并将时间缩短到 50 毫秒左右。

我的数据是嵌套多个类型数组的几何数据结构。我有将所有数据提取到 JSON + ArrayBuffer 对象数组的方法,因此我可以将传输的数据传递给 WebWorker,而无需复制大数组。

  • 我已经测试了数据传输,并确认它按预期工作。传输到 WebWorker 后,我的类型化数组在主线程中为空。
  • 我(目前)预先启动了 4 个 Web Worker,以便在需要完成工作时,Worker 应该准备就绪。
  • 当每个工作人员完成一项任务时,我将其放入队列中的下一个任务,直到队列为空。
  • 我跟踪 web worker 的时间,看看有多少时间用于实际计算(例如,忽略数据传输开销)。
  • 我有一台 8 核笔记本电脑,每天运行多线程代码。

这是我的 WebWorker 脚本。

importScripts('../lib/MyLib.js');

let timeComputing = 0;  
this.onmessage = function(e) {
  switch (e.data.msg) {
    case 'compute':
        let mesh = ... unpack data;
        let start = performance.now();
        mesh.doexpensiveCompute();
        timeComputing += performance.now() - start;
        ... send data back to the main thread.
        break;
    case 'logTime':
        console.log("timeComputing:" + timeComputing);
  }
}

当 worker 记录正在使用的时间时,通常每个 worker 大约 130 毫秒,这意味着总时间实际上将近 500 毫秒。主线程在 250 毫秒内完成所有工作,所以我使用 WebWorkers 的速度要慢 100%。出于某种原因,在 WebWorker 中运行完全相同的代码比在主线程中运行要慢得多。

我很快就会有一些工作负载可能有数百个任务,所以我希望 WebWorkers 能让我的页面保持响应。 (目前它根本不在大负载上)。

对于我为什么会看到如此糟糕的结果,有人能提出任何建议吗?注意:我在这里消除了数据传输成本(我认为这是最小的)和线程启动。我纯粹是在测量 worker 的计算时间,这很糟糕……有没有人有在 webworker 中运行繁重计算任务的经验?

一个想法是,我的工作脚本也会加载我的主引擎脚本。 (示例代码中的 MyLib.js),这是一个 Webpacked 脚本,而且相当大。我使用它是为了希望浏览器缓存意味着它不需要再次请求它。也许我应该只为 webworker 上下文生成我的引擎的最小版本。

感谢任何提示...

最佳答案

我现在已经调试了我的 Worker。

importScripts('../lib/MyLib.js');

最初,我以为在 worker 中重新使用我的主库 js 文件将使浏览器能够使用缓存版本的库。 IE。浏览器不需要 HTTP 请求文件或编译它,因为它已经在内存中。事实证明这是错误的,浏览器需要重新请求文件并重新编译它。

因为我的脚本很大,重新编译成了一个很大的开销,因为它似乎还需要为每个线程重新编译它。我通过测量每项任务的往返时间得出这个结论,同时在 worker 中执行零工作。每个线程的往返时间开始时非常高 (300 毫秒),并在几次迭代后迅速下降到 < 1="">

我现在使用内联网络 worker 来避免额外请求并保持我的库封装,如下所述:http://www.html5rocks.com/en/tutorials/workers/basics/#toc-inlineworkers 并且还为工作人员使用一个简化的脚本到最低限度。

我现在的表现非常出色。 250 毫秒为 ~50 毫秒。第一次往返很慢,但还算不错,内联 web worker 使它快了很多。

关于javascript - WebWorkers 的执行似乎比主线程慢得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39419116/

有关javascript - WebWorkers 的执行似乎比主线程慢得多的更多相关文章

  1. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  2. ruby - Chef 执行非顺序配方 - 2

    我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul

  3. ruby - 为什么 Ruby 的 each 迭代器先执行? - 2

    我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试

  4. ruby - 检查是否通过 require 执行或导入了 Ruby 程序 - 2

    如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby​​文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否

  5. postman——集合——执行集合——测试脚本——pm对象简单示例02 - 2

    //1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json

  6. ruby-on-rails - rbenv:从 RVM 移动到 rbenv 后,在 Jenkins 执行 shell 中找不到命令 - 2

    我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions

  7. ruby-on-rails - 在 heroku 的 .fonts 文件夹中包含自定义字体,似乎无法识别它们 - 2

    Heroku支持人员告诉我,为了在我的Web应用程序中使用自定义字体(未安装在系统中,您可以在bash控制台中使用fc-list查看已安装的字体)我必须部署一个包含所有字体的.fonts文件夹里面的字体。问题是我不知道该怎么做。我的意思是,我不知道文件名是否必须遵循heroku的任何特殊模式,或者我必须在我的代码中做一些事情来考虑这种字体,或者如果我将它包含在文件夹中它是自动的......事实是,我尝试以不同的方式更改字体的文件名,但根本没有使用该字体。为了提供更多详细信息,我们使用字体的过程是将PDF转换为图像,更具体地说,使用rghostgem。并且最终图像根本不使用自定义字体。在

  8. ruby - 如何使用 Selenium Webdriver 根据 div 的内容执行操作? - 2

    我有一个使用SeleniumWebdriver和Nokogiri的Ruby应用程序。我想选择一个类,然后对于那个类对应的每个div,我想根据div的内容执行一个Action。例如,我正在解析以下页面:https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=puppies这是一个搜索结果页面,我正在寻找描述中包含“Adoption”一词的第一个结果。因此机器人应该寻找带有className:"result"的div,对于每个检查它的.descriptiondiv是否包含单词“adoption

  9. ruby-on-rails - Rake 任务仅调用一次时执行两次 - 2

    我写了一个非常简单的rake任务来尝试找到这个问题的根源。namespace:foodotaskbar::environmentdoputs'RUNNING'endend当在控制台中执行rakefoo:bar时,输出为:RUNNINGRUNNING当我执行任何rake任务时会发生这种情况。有没有人遇到过这样的事情?编辑上面的rake任务就是写在那个.rake文件中的所有内容。这是当前正在使用的Rakefile。requireFile.expand_path('../config/application',__FILE__)OurApp::Application.load_tasks这里

  10. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

随机推荐