调用方法的最快方式
阅读这篇文章我发现了几种调用方法的方法。
调用方法:
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 触发器中的方法,因此即使很小的速度提升也是有意义的。
Reading this article I found several ways to call a method.
Method to call:
public static void SendData(string value) { }
Calls:
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);
Is it true? Is it faster?
Action send = () => Send("Update");
send();
Or maybe this?
I need to call a method into a SQL CLR trigger with maximum performance so even small speed increase makes sense.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
哪个“更快”?
1)请鲍勃修剪你的草坪。等他说完了。然后去商场。
2)请鲍勃修剪你的草坪。当他给你修剪草坪时,去商场。
第二种方法可以让你更快地到达购物中心。您付出的代价是您不知道回家时草坪是否会被修剪。使用第一种技术,您知道当您从商场回家时,草坪将会被修剪,因为您一直等到它在您离开之前才修剪。如果您的逻辑取决于知道您回来时草坪已修剪完毕,那么第二种技术是错误的。
现在重要的是:显然这两种技术都比另一种技术修剪草坪的速度更快。当您问“哪种更快?”时您必须指出您正在测量速度的什么操作。
Which is "faster"?
1) Ask Bob to mow your lawn. Wait until he's done. Then go to the mall.
2) Ask Bob to mow your lawn. Go to the mall while he's mowing your lawn.
The second technique gets you to the mall a lot faster. The price you pay is that you have no idea whether the lawn is going to be mowed by the time you get home or not. With the first technique, you know that when you get home from the mall the lawn will be mowed because you waited until it was before you left in the first place. If your logic depends on knowing that the lawn is mowed by the time you get back then the second technique is wrong.
Now the important bit: Obviously neither technique gets your lawn mowed faster than the other. When you're asking "which is faster?" you have to indicate what operation you're measuring the speed of.
使用委托并不比直接调用方法更快(实际上,创建委托然后调用它会更昂贵)。
这看起来更快的原因是,直接调用该方法会在该方法运行时阻塞执行线程。您的委托示例异步调用该方法(使用
BeginInvoke
),以便调用线程在执行该方法时继续执行。此外,每当您在委托上调用 BeginInvoke 时,您还应该拥有相应的 EndInvoke,您在示例中缺少该 EndInvoke:
和
IanG on Tap:EndInvoke 不可选
Using a delegate is no faster than directly calling the method (in all reality, creating a delegate and then calling it would be more expensive).
The reason that this is going to seem faster is because directly calling the method blocks the executing thread while the method runs. Your delegate example calls the method asynchronously (using
BeginInvoke
) so the calling thread continues to execute while the method is executed.Also, whenever you have a call to BeginInvoke on a delegate you should also have the corresponding EndInvoke, which you're missing in your example:
Is EndInvoke() optional, sort-of optional, or definitely not optional?
and
IanG on Tap: EndInvoke Not Optional
从
SendData
返回调用者的角度来看,它是安慰剂速度的改进。BeginInvoke
将采用一个ThreadPool
线程并在该线程上启动该方法,然后立即返回调用者 - 实际工作在另一个线程上。无论线程处于何种状态,完成这项工作所需的时间都将保持不变。它可能会提高应用程序的响应能力,具体取决于工作,但委托并不比直接方法调用更快 - 正如我所说,在您的情况下,它似乎更快,因为它立即返回。试试这个:将
BeginInvoke
更改为Invoke
- 调用者现在处于阻塞状态,与正常调用SendData
相同。假设代码注释不是您的(即“推荐用于生产”),我会快速找到负责的开发人员,并确保他们了解
Delegate.BeginInvoke
以及他们正在使他们的应用程序具有多重功能的事实-线程化但没有意识到......要回答这个问题,直接方法调用始终是最快的方法 - 委托或反射会产生开销。
Its a placebo speed improvement from the point of view of when
SendData
is returning to the caller.BeginInvoke
will take aThreadPool
thread and start the method on that thread, then return to caller immediately - the actual work is on another thread. The time it takes to do this work will remain the same regardless of the thread its on. It might improve the responsiveness of your application, depending on the work, but delegates are not faster than direct method calls - as I say, in your situation it seems faster because it returns immediately.Try this: change
BeginInvoke
toInvoke
- the caller is now blocking, the same as callingSendData
normally.Assuming the code comments are not yours (ie, "RECOMMENDED FOR PRODUCTION") I would fast find the developer responsible and make sure they are aware of
Delegate.BeginInvoke
and the fact that they are making their app multi-threaded without realising it...To answer the question, a direct method call is always the fastest way - delegates or reflection incur overhead.
提高性能的最佳机会是优化触发器将调用的 SQL CLR 存储过程中的方法中的代码。您能发布更多相关信息吗?
Your best chance to increase performance would be to optimize the code in the method that will be in the SQL CLR stored procedure that the trigger will call. Could you post more information about that?
请注意,在您引用的文章中,作者正在谈论 WCF 调用,特别是插入和更新数据库的调用。
在该特定情况下需要注意的要点是:
因此,在这种特定情况下,后台调用更好。对于一般用途,直接调用更好。
Note that in the article you cite, the author is talking about WCF calls, notably calls for inserting and updating a database.
The keys points to note in that specific case are:
Hence, in that specific case, the background call were better. For general purpose use, direct calls are better.