问题 WCF比运行相同代码的WebAPI慢得多


我目前有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: 谢谢你的回答/评论。不幸的是,这个问题似乎没有任何结论。我和我的同事最终选择相信这只是Framework版本效率的一个纯粹差异。我们最终重组了Web服务,以便只在WebAPI中进行计算。


10311
2017-10-16 21:40


起源

那么你至少可以包括ProcessData代码以及你如何测量时间,只是为了让人们确信你没有错过任何东西。既然你提到了不同的.net版本,我想它们运行在不同的机器上? - Evk
进程代码太长,它包含在大约20个文件中(可能接近500行)。它们运行在同一台机器上,各个dll只是用不同的.NET版本构建。使用c#测量时间 StopWatch,在打电话之前和之后开始和停止 process(data) - Callback Kid
好吧,我无法想象可能会导致这种差异的原因。也许他们在不同优先级的流程中运行? - Evk
如果您使用以下方法强制您的WCF应用程序在更高版本的.NET上运行,该怎么办 docs.microsoft.com/en-us/dotnet/framework/migration-guide/...? - Evk
@Evk这不是我们的选择,在WCF服务的一些模块不能升级,过去的3.5没有重大重构/重写应用程序由于对旧框架的依赖性。 - Callback Kid


答案:


使用分析器

在没有任何麻烦的情况下,获得更好的数据。分析CPU使用率和内存,GC集合,热路径等...

那说......

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

.NET 4.6为64位引入了一个新的JIT,速度要快得多。这只是一个区别。列表太多了。

如果你不能改变.NET版本 决不 获得准确的基准,但可以寻找嫌疑人。我绝对会使用分析器,但如果基准测试:

看看生成的 IL (预JIT)并确保您对JIT后的基准(IL - >机器代码)。

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

另一种是使用 RuntimeHelpers.PrepareMethod 在JIT方法的基准之前,所以你不是在测量JIT时间。

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

有很多信息,但确保你使用高分辨率计时器,使用大样本(重复多次),做一个 GC.Collect() 在每次测量之前,使用相同的硬件(在同一个盒子上测试)等...

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

其他任何事情都只是我们的猜测。除非你发布了能重现你行为的真实代码,否则我无法发表评论。


4
2017-10-25 22:25



@Evk这不是真的。即使他在同一台机器上运行。该机器一次可以容纳不同的.NET版本。例如,我有所有.NET版本从.NET框架2到.NET框架4.7.1和.net核心1,.NET核心1.1和.net芯2一路每个项目选择被配置为运行的运行不是最新的。 - Nick Polideropoulos
@NickPolideropoulos以及至少它可能是他们在同.NET版本上运行,身价由OP检查,如果他们还是不(他的3.5服务可能会在4.6版本我的意思是运行)。如果没有 - 强制3.5在更高版本上运行,看看是否有助于解决问题 - Evk
@Zer0你能推荐一个分析器吗?此时(参见我的第二次编辑)我们放弃了这项工作,但我仍然很想找到一些结果。 - Callback Kid
@CallbackKid我个人根据情况使用了很多(都有利弊)。首先,我会推荐Red Gate的“ANTS”用于性能,而SciTech的“.NET Memory Profiler”用于内存。我可能还应该提一下,进行数据包捕获和检查可能是值得的。使用类似Wireshark的东西。这为您提供了详细的网络级信息。我不是YMMV的粉丝,但Visual Studio有一个内置的分析器。 - Zer0


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

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


3
2017-10-23 08:46





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


2
2017-10-16 21:43



测量的性能不包括网络时间。所以我没有想象它可能是一个REST / SOAP问题。至于初始化时间,这是可能的,但我只在一个实例中看到这个减慢,而不是在端点之间的其他共享调用中。 - Callback Kid
疑难杂症。说实话,我看到WCF和WebAPI也有些缓慢,并且对此感到困惑,也许我可以深入研究它。 IIRC必须为WebAPI发生的是为方法调用实例化的ApiController,它应该比初始化WCF服务更快。 - Ratatoskr
因此,如果我在一次服务调用中多次运行计算,我应该看到后续计算的性能提升? - Callback Kid
是的,如果缺乏性能是由于初始化,我会说这将是你所看到的。 - Ratatoskr
虽然,看看你的图表,我不确定是这样的。不过,它仍然值得测试。 - Ratatoskr


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

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

因此,在编码之前,最好知道每个框架做得最好并相应地选择。


1
2017-10-25 06:11