Laut diesem Artikel ist WCF mit benannten Pipes die beste Wahl für IPC und etwa 25 % schneller als .Net Remoting.
Ich habe den folgenden Code, der WCF mit benannten Pipes mit .Net Remoting vergleicht:
[ServiceContract]
internal interface IRemote
{
[OperationContract]
string Hello(string name);
}
[ServiceBehavior]
internal class Remote : MarshalByRefObject, IRemote
{
public string Hello(string name)
{
return string.Format("Hallo, {0}!", name);
}
}
class Program
{
private const int Iterationen = 5000;
static void Main(string[] args)
{
TestWcf(Iterationen);
TestRemoting(Iterationen);
TestWcf(Iterationen);
TestRemoting(Iterationen);
TestWcf(Iterationen);
TestRemoting(Iterationen);
Console.ReadKey();
}
private static void TestRemoting(int iterationen)
{
var domain = AppDomain.CreateDomain("TestDomain");
var proxy =
(IRemote)
domain.CreateInstanceFromAndUnwrap(Assembly.GetEntryAssembly().Location, "ConsoleApplication6.Remote");
Console.WriteLine("Remoting: {0} ms.", Test(proxy, iterationen));
}
private static void TestWcf(int iterationen)
{
var address = "net.pipe://localhost/test";
var host = new ServiceHost(typeof (Remote));
host.AddServiceEndpoint(typeof (IRemote), new NetNamedPipeBinding(), address);
host.Open();
var proxy = ChannelFactory.CreateChannel(new NetNamedPipeBinding(), new EndpointAddress(address));
Console.WriteLine("Wcf: {0} ms.", Test(proxy, iterationen));
host.Close();
}
private static double Test(IRemote proxy, int iterationen)
{
var start = DateTime.Now;
for (var i = 0; i < iterationen; i++)
{
proxy.Hello("Sergey");
}
var stop = DateTime.Now;
return (stop - start).TotalMilliseconds;
}
}
Die Ergebnisse für 5000 Iterationen lauten wie folgt:
Wcf: 14143 ms.
Remoting: 2232 ms.
Wcf: 14289 ms.
Remoting: 2130 ms.
Wcf: 14126 ms.
Remoting: 2112 ms.
In diesem Test ist WCF etwa 7 mal langsamer als .Net Remoting.
Ich habe versucht:
- den Sicherheitsmodus auf None zu setzen;
- den InstanceContextMode auf Single/PerCall zu setzen;
- den ConcurrencyMode auf Single/Multiple zu setzen;
aber die Ergebnisse sind die gleichen.
Weiß jemand, was ich falsch mache? Warum ist WCF so langsam?
Gibt es eine Möglichkeit, diesen Code zu beschleunigen?
Vielen Dank im Voraus.
EDIT:
Ich habe den Test etwas modifiziert. Der Vertrag ist der gleiche.
Der erste Test sieht so aus (Wcf-Test):
class Program
{
private const int Iterationen = 5000;
static void Main(string[] args)
{
var address = "net.pipe://localhost/test";
var host = new ServiceHost(typeof(Remote));
host.AddServiceEndpoint(typeof(IRemote), new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), address);
host.Open();
var proxy = ChannelFactory.CreateChannel(new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), new EndpointAddress(address));
TestWcf(proxy, Iterationen);
TestWcf(proxy, Iterationen);
TestWcf(proxy, Iterationen);
TestWcf(proxy, Iterationen);
TestWcf(proxy, Iterationen);
Console.ReadKey();
host.Close();
}
private static void TestWcf(IRemote proxy, int iterationen)
{
var start = DateTime.Now;
for (var i = 0; i < iterationen; i++)
{
proxy.Hello("Sergey");
}
var stop = DateTime.Now;
Console.WriteLine("Wcf: {0} ms.", (stop - start).TotalMilliseconds);
}
}
Hier sind die Ergebnisse:
Wcf: 2564 ms.
Wcf: 1026 ms.
Wcf: 986 ms.
Wcf: 990 ms.
Wcf: 992 ms.
Der zweite Test sieht so aus (.Net Remoting-Test):
class Program
{
private const int Iterationen = 5000;
static void Main(string[] args)
{
var domain = AppDomain.CreateDomain("TestDomain");
var proxy =
(IRemote)
domain.CreateInstanceFromAndUnwrap(Assembly.GetEntryAssembly().Location, "ConsoleApplication6.Remote");
TestRemoting(proxy, Iterationen);
TestRemoting(proxy, Iterationen);
TestRemoting(proxy, Iterationen);
TestRemoting(proxy, Iterationen);
TestRemoting(proxy, Iterationen);
Console.ReadKey();
}
private static void TestRemoting(IRemote proxy, int iterationen)
{
var start = DateTime.Now;
for (var i = 0; i < iterationen; i++)
{
proxy.Hello("Sergey");
}
var stop = DateTime.Now;
Console.WriteLine("Remoting: {0} ms.", (stop - start).TotalMilliseconds);
}
}
Hier sind die Ergebnisse:
Remoting: 261 ms.
Remoting: 224 ms.
Remoting: 252 ms.
Remoting: 243 ms.
Remoting: 234 ms.
Wie Sie sehen können, ist .Net Remoting wieder schneller. Die Tests wurden außerhalb des Debuggers durchgeführt.
Warum ist das so?