调用方法的最快方法

时间:2010-07-21 14:50:45

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

阅读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触发器中,因此即使很小的速度增加也是有意义的。

5 个答案:

答案 0 :(得分:20)

哪个“更快”?

1)让鲍勃修剪你的草坪。等到他完成了。然后去商场。

2)让鲍勃修剪你的草坪。在修剪你的草坪时去商场。

第二种技术让你快速进入商场。您支付的价格是,您不知道在您回家的时候草坪是否会被修剪。使用第一种技术,您知道当您从商场回家时,草坪将被修剪,因为您等到它离开之前是第一个地方。如果您的逻辑依赖知道草坪在您回来的时候被割草,那么第二种技术错误

现在重要一点:显然,这两种技术都没有让你的草坪比另一种更快。当你问“哪个更快?”你必须指出你正在测量的速度

答案 1 :(得分:13)

使用委托并不比直接调用该方法快(在所有情况下,创建委托然后调用它会更加昂贵)。

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

此外,每当您在委托上调用BeginInvoke时,您还应该拥有相应的EndInvoke,您在示例中缺少该内容:

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

IanG on Tap: EndInvoke Not Optional

答案 2 :(得分:2)

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

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

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

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

答案 3 :(得分:1)

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

答案 4 :(得分:1)

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

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

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

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