【问题标题】:WCF much slower than WebAPI running same codeWCF 比运行相同代码的 WebAPI 慢得多
【发布时间】:2018-03-28 12:26:00
【问题描述】:

我目前有 2 个暴露的端点。第一个是 WebAPI (.NET 4.6)。第二个是 WCF (.NET 3.5)。它们都能够执行相同的计算,但是 WCF 平均慢 10 倍。有问题的计算代码包含在一个 dll 中,我们称之为 core.dll。此 dll 还公开 WCF 端点并由 ASP.NET 站点使用。 webapi dll,我们称之为 api.dll 引用 core.dll 并由 SPA 使用。计算可以由任一客户端触发。平均而言,根据我的测试数据,WCF 服务大约需要 4.5 秒来执行计算,而 WebAPI 大约需要 450 毫秒(或大约快 10 倍)。

我应该注意,所有数据库调用都是在测量的时间范围之外完成的。所有数据都是事先检索的,所有更新都是在计算完成后进行的。

在所有条件相同的情况下,我有什么理由看到纯粹的处理速度有这么大的差异?

我 100% 确定两个客户端的数据相同,并且它们都收到相同的结果。

WEBAPI Controller
    Service
        GRAB DATA
        start timer
        Process(DATA) -- the same code/class as below
        end timer
        UPDATE DATA
    Service return
WEBAPI Controller return

WCF Endpoint
    Service
        GRAB DATA
        start timer
        Process(DATA) -- the same code/class as above
        end timer
        UPDATE DATA
    Service return
WCF Endpoint return

编辑:为清楚起见添加了图表(希望如此)

编辑 2: 感谢您的答案/ cmets。不幸的是,这个问题看起来不会有任何决定性的结果。我和我的同事最终选择相信这只是框架版本效率的纯粹差异。我们最终对 Web 服务进行了重组,以便只在 WebAPI 中进行计算。

【问题讨论】:

  • 好吧,您至少可以包含 ProcessData 代码以及您如何测量时间,只是为了让人们确保您没有遗漏任何东西。另外,由于您提到了不同的 .net 版本,我想它们在不同的机器上运行?
  • 流程代码太长,大概有20个文件(大概接近500行)。它们在同一台机器上运行,各个 dll 只是使用不同的 .NET 版本构建的。使用c#StopWatch测量时间,在调用process(data)之前和之后开始和停止
  • 那么我无法想象是什么导致了这种差异。也许它们在具有不同优先级的进程中运行?
  • 如果你强制你的 WCF 应用程序运行在更高版本的 .NET 上使用这个:docs.microsoft.com/en-us/dotnet/framework/migration-guide/…
  • @Evk 这对我们来说不是一个选项,由于对旧框架的依赖,WCF 服务中的某些模块无法在不对应用程序进行重大重构/重写的情况下升级到 3.5 以上。

标签: c# .net wcf asp.net-web-api


【解决方案1】:

使用分析器

无需任何麻烦即可获得更好的数据,无需处理。分析 CPU 使用率和内存、GC 收集、热路径等...

也就是说……

您正在比较两个截然不同的 .NET 版本。这使得无法进行公平的基准测试。

.NET 4.6 为 64 位引入了一个新的 JIT,它明显更快。这只是其中一个区别。太多了,无法列出。

如果您无法更改 .NET 版本,您将永远不会获得准确的基准,但可以寻找可疑对象。我绝对会使用分析器,但如果进行基准测试:

查看生成的 IL(JIT 前)并确保您对 JIT 后(IL -> 机器代码)进行基准测试。

一种简单的方法是在开始实际基准测试之前将两个基准测试运行一次(未测量)作为“冷启动”。

另一种方法是在 JIT 方法的基准测试之前使用 RuntimeHelpers.PrepareMethod,这样您就不会测量 JIT 时间。

当然,请确保您的基准是公平的。

那里有大量信息,但请确保您使用的是高分辨率计时器,使用大样本量(重复多次),每次测量前执行GC.Collect(),使用相同的硬件(在同一个盒子上测试)等等……

在进程中正确地进行基准测试(而不是分析)确实不是 看起来很简单。

其他的只是我们的猜测。除非您发布可以重现您行为的真实代码,否则我无法真正发表评论。

【讨论】:

  • @Evk 这不是真的。即使他在同一台机器上运行。机器一次可以容纳不同的 .NET 版本。例如,我拥有从 .net framework 2 到 .net framework 4.7.1 和 .net core 1、.net core 1.1 和 .net core 2 的所有 .net 版本。每个项目都选择配置为运行的运行时不是最新的。
  • @NickPolideropoulos 至少它们有可能在相同的 .NET 版本上运行(我的意思是他的 3.5 服务可能在 4.6 版本上运行),值得由 OP 检查它们是否存在。如果没有 - 强制 3.5 在更高版本上运行,看看是否有助于解决问题
  • @Zer0 你能推荐一个分析器吗?在这一点上(见我的第二次编辑)我们已经放弃了这项工作,但我仍然很想找到一些结果。
  • @CallbackKid 我个人根据情况使用一个广泛的数字(都有优点和缺点)。作为开始,我会推荐 Red Gate 的“ANTS”用于性能,而 SciTech 的“.NET Memory Profiler”用于内存。我可能还应该提到进行数据包捕获和检查可能是值得的。使用类似于 Wireshark 的东西。这为您提供了详细的网络级信息。我不是 YMMV 的粉丝,但 Visual Studio 有一个内置的分析器。
【解决方案2】:

我认为您会看到这样的差异,因为从 .net 3.5 到 .net 4.6 有很大的性能提升。如果您大量使用可能是问题的框架元素。

查看下面的链接(它们包含有关性能提升的信息):

【讨论】:

    【解决方案3】:

    我认为这是几件事的结合。即 REST (WebAPI) 与 SOAP (WCF) 的性能,尤其取决于发送/接收的数据量。除了在 ASP.NET 中托管 WCF 服务这一事实之外,我认为该服务在被调用之前实际上并未运行或初始化,因此您将有一些初始化时间。

    【讨论】:

    • 实测性能不包括网络时间。所以我不认为它可能是一个 REST/SOAP 问题。至于初始化时间,这是可能的,但我只在一个实例中看到这会变慢,而不是在端点之间的其他共享调用中。
    • 明白了。老实说,我也看到了 WCF 与 WebAPI 的一些缓慢并且对此感到困惑,也许我可以进一步深入研究它。 IIRC WebAPI 所要做的就是为方法调用实例化 ApiController,这应该比初始化 WCF 服务更快。
    • 因此,如果我在一次服务调用中多次运行计算,我应该会看到后续计算的性能提升?
    • 是的,如果性能不足是由于初始化,我会说这就是您所看到的。
    • 虽然,看看你的图表,我不确定情况是否如此。不过,它仍然值得测试。
    【解决方案4】:

    除了此处其他答案中提到的性能改进之外,我想指出在 WCF 和 Web API 之间进行选择的一个非常重要的区别:

    1. 您可以从它们中获得相同的结果,但 WebAPI 旨在与 HTTP(主要与 JSON)和 WCF 一起使用需要更多配置才能成为 HTTP(SOAP 作为默认消息传递)。
    2. WCF 支持多种传输协议,例如消息队列、单向消息传递或双工、TCP,当然还有 HTTP 等等。
    3. WCF 可以这样配置,当上面的 1 个可用并且比其他的更快时,它可以像 TCP 甚至 UDP 一样使用(在更高版本上)...
    4. 当然,这些通道中的每一个都需要配置,这有时会让人头疼。
    5. WebAPI 旨在与 HTTP 一起使用,因此它支持请求/响应、标头、媒体格式(文本、JSON、 jpeg、XML...)、URI、缓存等等。
    6. SOAP 处理和传输比 JSON 更“重”。时期。这是过去 10 年左右更喜欢 JSON 而不是 XML 的主要原因。
    7. 当您的服务可以暴露给大量客户端(主要是浏览器,也包括移动设备)时,选择 Web API!
    8. WebAPI 是一个轻量级框架,适用于带宽有限的智能手机。
    9. 如前所述,客户端已经发展成为强大的框架,例如 JQuery、Angular、Android 等。所有人都需要从服务中快速传输数据。目前,JSON 是在客户端和服务器之间处理数据最简单、最快捷的方式,WebAPI 可以与之无缝协作。

    所以在编码之前最好了解每个框架最擅长的地方并做出相应的选择。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-27
      • 1970-01-01
      • 2017-01-19
      • 1970-01-01
      • 2013-08-08
      • 1970-01-01
      • 2016-10-23
      • 1970-01-01
      相关资源
      最近更新 更多