【问题标题】:The fastest way to call a method调用方法的最快方式
【发布时间】:2010-07-21 14:50:45
【问题描述】:

阅读this article我发现了几种调用方法的方法。

调用方法:

public static void SendData(string value) { }

来电:

delegate void MyDelegate(string value);

//Slow method - NOT RECOMMENDED IN PRODUCTION!        
SendData("Update");

// Fast method - STRONGLY RECOMMENDED FOR PRODUCTION!
MyDelegate d = new MyDelegate(SendData);
d.BeginInvoke("Update", null, null);

这是真的吗?是不是更快?

Action send = () => Send("Update");
send();

或者这个?

我需要将一个方法调用到具有最高性能的 SQL CLR 触发器中,因此即使是很小的速度提升也是有意义的。

【问题讨论】:

  • 如果你仔细想想,不让直接方法调用最快的方法调用方法的原因是什么? CLR 针对常见情况(直接方法调用)进行了大量优化。让委托调用比直接方法调用更快是没有意义的。
  • 为什么不加评论就投反对票??

标签: c# .net delegates lambda method-call


【解决方案1】:

哪个“更快”?

1) 让 Bob 帮您修剪草坪。等他说完。然后去商场。

2) 让 Bob 帮您修剪草坪。在他修剪你的草坪时去商场。

第二种方法可以让您更快地到达购物中心。你付出的代价是你不知道你回家时草坪是否会被修剪。使用第一种技术,您知道当您从商场回家时,草坪将被修剪,因为您一开始就等到它离开之前。如果你的逻辑依赖在你回来的时候知道草坪已经修剪,那么第二种方法是错误的

现在最重要的一点是:显然这两种技术都能让你的草坪修剪得更快。当你问“哪个更快?”你必须指出什么操作你正在测量速度。

【讨论】:

  • 现在如果 Alice 想给 Bob 发消息怎么办? (j/k)
  • @JesseC.Slicer 这很简单。只需创建一个全新的“cryptografically supersecurez (TM)”系统,而不是依赖现有的交换机制。
  • @MateenUlhaq 滚动你自己的割草机被认为是有害的。
【解决方案2】:

使用委托并不比直接调用方法快(实际上,创建委托然后调用它会更昂贵)。

这看起来更快的原因是因为直接调用方法会在方法运行时阻塞正在执行的线程。您的委托示例异步调用方法(使用BeginInvoke),因此调用线程在方法执行时继续执行。

此外,每当您在委托上调用 BeginInvoke 时,您还应该有相应的 EndInvoke,而您的示例中没有:

Is EndInvoke() optional, sort-of optional, or definitely not optional?

IanG on Tap: EndInvoke Not Optional

【讨论】:

  • 我相信调用委托的速度与在接口上调用方法的速度大致相同(由于所有指针与方法表和对象查找的争吵)。不记得我在哪里读到的
  • @thecoop - 但是您仍然需要增加创建委托的开销,而不仅仅是调用它。
  • 以及在这种情况下选择ThreadPool 线程的开销。
【解决方案3】:

SendData 何时返回给调用者的角度来看,这是一个安慰剂速度提升。 BeginInvoke 将采用 ThreadPool 线程并在该线程上启动方法,然后立即返回调用者 - 实际工作在另一个线程上。无论线程处于何种状态,完成这项工作所需的时间都将保持不变。它可能会提高您的应用程序的响应能力,具体取决于工作,但委托并不比直接方法调用快 - 正如我所说,在您的情况下它似乎更快,因为它会立即返回。

试试这个:将BeginInvoke 更改为Invoke - 调用者现在阻塞,与正常调用SendData 相同。

假设代码 cmets 不是您的(即“推荐用于生产”),我会很快找到负责的开发人员并确保他们知道 Delegate.BeginInvoke 以及他们正在使他们的应用程序多线程而没有意识到的事实它...

要回答这个问题,直接方法调用始终是最快的方法 - 委托或反射会产生开销。

【讨论】:

    【解决方案4】:

    提高性能的最佳机会是优化触发器将调用的 SQL CLR 存储过程中的方法中的代码。您能否发布更多相关信息?

    【讨论】:

    • 在这种情况下,CLR 触发器调用的不是 CLR sp,而是 WCF Web 服务。用于测试目的。但很可能它会调用十几种不同的方法来执行业务逻辑(订单状态发生变化)。
    【解决方案5】:

    请注意,在您引用的文章中,作者谈论的是 WCF 调用,尤其是插入和更新数据库的调用。

    在这种特定情况下需要注意的关键点是:

    • 工作正在由另一台机器完成。
    • 您得到的唯一信息是“成功!” (通常)或(偶尔)“失败”(作者似乎并不关心)

    因此,在这种特定情况下,后台调用更好。对于一般用途,直接调用更好。

    【讨论】:

    • 据我所知,性能主题只是关于方法调用和其他 - 关于 WCF 调用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-30
    • 1970-01-01
    • 1970-01-01
    • 2011-05-28
    • 1970-01-01
    • 2013-03-11
    • 2016-03-31
    相关资源
    最近更新 更多