【问题标题】:Need Blazor Wasm Performance Improvement on CPU Intensive Calculations在 CPU 密集型计算上需要 Blazor Wasm 性能改进
【发布时间】:2021-03-11 02:53:24
【问题描述】:

我有一个已转换为 Blazor Wasm 的 c# WinForms 应用程序。在大多数用户输入之后,它需要执行一组 CPU 密集型计算(即没有 IO 或 UI 交互)。计算需要重复(30-50 次)调用一组 25-35 个 C# 类对象中的许多方法,具体取决于场景。相同的计算代码在 WinForms 和 Blazor 应用程序中运行。

我看到 Blazor 下的性能下降了约 20 倍(例如,WinForms 中的 350 毫秒与 Blazor 中的 7000 毫秒)。这种程度的退化有意义吗?它的很大一部分是在浏览器中运行所固有的吗? Blazor Wasm 在某种程度上是它的重要组成部分吗?我已经确认退化分布在计算中,而不是孤立的点。有什么方法可以显着减少退化?如果出于某种原因可能会有所帮助,可以将执行计算的对象放入类库中。

我已经在 GitHub 的 AspNetCore 讨论中发布了这个问题,但没有得到任何回复。我正在使用 VS Community 2019 v16.8.2、AspNetCore 5.0 和 Chrome v

谢谢。史蒂夫

【问题讨论】:

  • 是的,这是预期的性能下降。 Blazor wasm 现在以解释器模式运行(尽管在不久的将来可能会发生变化),这意味着只有运行时本身被编译为 wasm。然后,运行时从您的 dll 下载并解释 IL,与将程序集直接编译为 WASM 的情况相比,这非常慢。很快它应该可以直接编译成 WASM,并且它应该会提供一些性能改进(尽管它无论如何都不会达到原生 .NET 应用程序的水平)
  • 呃。我希望这不是答案。我有相当长的时间来等待编译被实现,但是这将有助于了解在改进之后与本机 .NET 相比有多少退化。慢 2-3 倍可能是可行的(可能有一些逻辑上的妥协),但 5+ 可能是一个阻碍。无论如何,谢谢你的观点。
  • 很难说(对我来说)这将实现什么加速,可能确实会慢 3 倍。但是,Blazor wasm 也不支持多线程,尽管 WASM 本身支持(至少在某些浏览器中,最终会有更多的浏览器支持它)。虽然直接编译到 wasm 即将到来 - 我不知道在不久的将来有任何关于多线程的计划。对于 CPU 密集型计算,可能会为原生 .NET 提供更多功能。
  • 我意识到这是几周前的事了,但我想我会检查你的计算是否涉及任何异步调用——你在等待什么吗?您在计算期间是否更新 UI?您是否正在消除用户输入的抖动,以防止计算在单个线程上通过异步同时运行?
  • 计算没有按照您的要求进行。纯cpu处理。有一个实例化的单例,它通过调用一组大约 40 个对象中的各种方法来控制计算。所有这些对象都会在启动时实例化,并在每次需要进行新一轮计算时重复使用。

标签: c# visual-studio asp.net-core blazor webassembly


【解决方案1】:

这是对这个问题的一个很晚的回答,但是网络工作者会帮助解决这个问题吗?这应该会带来一些多线程功能。我不能说自己实现这个,但这里有一个帮助库似乎可以很容易地将它带入 Blazor:

https://github.com/Tewr/BlazorWorker

在原生 JavaScript 中,您可以通过 Navigator Api 访问浏览器的核心数:

const coreCount = window.navigator.hardwareConcurrency;
console.log(`Your computer has ${coreCount} cores!`);

【讨论】:

  • 感谢您的建议。我可以看到它对某些需求有何帮助,但就我而言,计算需要完全同步。
【解决方案2】:

如果您有 .NET 后端,则可以轻松地在那里执行代码。只需几毫秒的开销,您就可以获得与以前几乎相同的性能。双方使用相同语言的好处之一。

【讨论】:

  • 我很欣赏这个想法,可能不得不走这条路。我希望仅出于几个原因制作/保留应用程序客户端,主要是能够声称用户的信息完全保存在他们的计算机上。从技术上讲,该应用程序将其保存在 IndexedDB 中。如果由于性能原因证明不可行,那么我将考虑使用客户端-服务器。
【解决方案3】:

将浏览器中运行的程序与操作系统中本机运行的程序进行比较可能不公平。我宁愿将 Blazor 与 JavaScript 进行比较,因为它们都在浏览器上运行。可以在浏览器中运行的程序的优势在于它可以在大多数设备上运行,从 PC 到大多数手机。此外,它是一种 MSIL 形式,比 JavaScript 更难逆向工程。但是,要付出代价,那就是性能(Mono 中的 MSIL -> WASM -> Native)。

【讨论】:

  • 感谢您的观点。我正在比较 WinForms 与 Blazor 的性能,因为我有那个代码,而不是它的 JS 版本。最后,我需要的是在 Blazor 下更好的性能。
【解决方案4】:

如果它是纯粹的计算,那么为什么不使用 WASM 语言(例如 Rust)并直接从 JavaScript 调用它?正如 Josef 指出的那样,您还可以使用服务器端 Blazor 或简单地调用 Web 服务端点。

【讨论】:

  • 感谢大家的建议。已经用 C# 编写和调试了大量代码,因此转换为其他语言并不是一个非常有吸引力的选择。转移到 Blazor Server 模型是一种选择,尽管由于添加了额外的变量,我一直试图避免这种情况。出于这两个原因,我开始使用 Blazor Wasm 路径,仅限 C# 和客户端。
  • 我希望编译后的 Blazor 能够运行良好。我在 AspNetCore GitHub (github.com/dotnet/runtime/issues/45363) 中发布了一个问题,看看那些管理开发的人有什么要说的。
【解决方案5】:

Blazor 有两种托管模型:Blazor 客户端模型和 Blazor 服务器模型。此处的详细信息:Blazor Hosting Models 如果您使用 Blazor 客户端,我预计会出现这种降级,但在 Blazor Server 中不会出现这种情况。

【讨论】:

    【解决方案6】:

    Blazor Wasm 不支持多线程 + 鼠标事件处理等频繁操作对于在浏览器中进行处理非常“繁重”。尝试将动作处理程序推送到队列中并在后台处理它们。

    【讨论】:

    • 如果直接编译不足以提高性能,恐怕我可能需要从用户的角度彻底重新考虑它的工作方式。恐怕将事情推入队列以进行后台处理不是解决方案。无论如何,谢谢你的想法。
    猜你喜欢
    • 2011-04-11
    • 2012-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-18
    • 2023-01-10
    相关资源
    最近更新 更多