views:

252

answers:

5

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.

+13  A: 

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

Justin Niessner
thecoop
@thecoop - But you still have to add in the overhead of creating the delegate, not just calling it.
Justin Niessner
And the overhead of selecting a `ThreadPool` thread in this instance.
Adam
+2  A: 

Its a placebo speed improvement from the point of view of when SendData is returning to the caller. BeginInvoke will take a ThreadPool 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 to Invoke - the caller is now blocking, the same as calling SendData 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.

Adam
+1  A: 

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?

P.McSwain
In this case, CLR trigger calls not a CLR sp but WCF web service. For testing purpose. But most likely it will call a dozen of different methods which performs business logic (on order status changed).
abatishchev
+17  A: 

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.

Eric Lippert
Now what if Alice wants to send Bob a message? (j/k)
Jesse C. Slicer
+1  A: 

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:

  • The work is being done by another machine.
  • The only information you are getting back is "Success!" (usually) or (occasionally) "Failure" (which the author doesn't seem to care about)

Hence, in that specific case, the background call were better. For general purpose use, direct calls are better.

James Curran
As far as I could understand performance topic just is about method calls and in other - about WCF calls
abatishchev