简体   繁体   English

WCF与.Net Remoting

[英]WCF vs. .Net Remoting

according to this article , WCF with named pipes is the best choice for IPC, and it is around 25 % faster than .Net Remoting. 根据这篇文章 ,带有命名管道的WCF是IPC的最佳选择,它比.Net Remoting快25%左右。

I have the following code that compares WCF with named pipes with .Net Remoting: 我有以下代码将WCF与命名管道与.Net Remoting进行比较:

[ServiceContract]
internal interface IRemote
{
    [OperationContract]
    string Hello(string name);
}

[ServiceBehavior]
internal class Remote : MarshalByRefObject, IRemote
{
    public string Hello(string name)
    {
        return string.Format("Hello, {0}!", name);
    }
}

class Program
{
    private const int Iterations = 5000;

    static void Main(string[] args)
    {
        TestWcf(Iterations);
        TestRemoting(Iterations);

        TestWcf(Iterations);
        TestRemoting(Iterations);

        TestWcf(Iterations);
        TestRemoting(Iterations);

        Console.ReadKey();
    }

    private static void TestRemoting(int iterations)
    {
        var domain = AppDomain.CreateDomain("TestDomain");

        var proxy =
            (IRemote)
            domain.CreateInstanceFromAndUnwrap(Assembly.GetEntryAssembly().Location, "ConsoleApplication6.Remote");

        Console.WriteLine("Remoting: {0} ms.", Test(proxy, iterations));
    }

    private static void TestWcf(int iterations)
    {
        var address = "net.pipe://localhost/test";

        var host = new ServiceHost(typeof (Remote));
        host.AddServiceEndpoint(typeof (IRemote), new NetNamedPipeBinding(), address);
        host.Open();

        var proxy = ChannelFactory<IRemote>.CreateChannel(new NetNamedPipeBinding(), new EndpointAddress(address));

        Console.WriteLine("Wcf: {0} ms.", Test(proxy, iterations));

        host.Close();
    }

    private static double Test(IRemote proxy, int iterations)
    {
        var start = DateTime.Now;

        for (var i = 0; i < iterations; i++)
        {
            proxy.Hello("Sergey");
        }

        var stop = DateTime.Now;

        return (stop - start).TotalMilliseconds;
    }
}

A got the following results for 5000 iterations: A获得了5000次迭代的以下结果:

Wcf: 14143 ms.
Remoting: 2232 ms.
Wcf: 14289 ms.
Remoting: 2130 ms.
Wcf: 14126 ms.
Remoting: 2112 ms.

Wcf is around 7 times slower than .Net Remoting in this test. 在此测试中,Wcf比.Net Remoting慢约7倍。

I tried to: 我试过了:

  • set the security mode to None; 将安全模式设置为None;
  • set the InstanceContextMode to Single/PerCall; 将InstanceContextMode设置为Single / PerCall;
  • set the ConcurrencyMode to Single/Multiple; 将ConcurrencyMode设置为Single / Multiple;

but the results are the same. 但结果是一样的。

Does anybody know what I do wrong? 有人知道我做错了什么吗? Why WCF is so slow? 为什么WCF这么慢?

Is there a way to speed up this code? 有没有办法加快这个代码?

Thanks in advance. 提前致谢。

EDIT: 编辑:

I have modified the test a little bit. 我已经修改了一点测试。 The contract is the same. 合同是一样的。

The first test looks like this (Wcf test): 第一个测试看起来像这样(Wcf测试):

class Program
{
    private const int Iterations = 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<IRemote>.CreateChannel(new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), new EndpointAddress(address));

        TestWcf(proxy, Iterations);
        TestWcf(proxy, Iterations);
        TestWcf(proxy, Iterations);
        TestWcf(proxy, Iterations);
        TestWcf(proxy, Iterations);

        Console.ReadKey();

        host.Close();
    }

    private static void TestWcf(IRemote proxy, int iterations)
    {
        var start = DateTime.Now;

        for (var i = 0; i < iterations; i++)
        {
            proxy.Hello("Sergey");
        }

        var stop = DateTime.Now;

        Console.WriteLine("Wcf: {0} ms.", (stop - start).TotalMilliseconds);
    }
}

Here are the results: 结果如下:

Wcf: 2564 ms.
Wcf: 1026 ms.
Wcf: 986 ms.
Wcf: 990 ms.
Wcf: 992 ms.

The second test looks like this (.Net Remoting test): 第二个测试看起来像这样(.Net Remoting测试):

class Program
{
    private const int Iterations = 5000;

    static void Main(string[] args)
    {
        var domain = AppDomain.CreateDomain("TestDomain");

        var proxy =
            (IRemote)
            domain.CreateInstanceFromAndUnwrap(Assembly.GetEntryAssembly().Location, "ConsoleApplication6.Remote");

        TestRemoting(proxy, Iterations);
        TestRemoting(proxy, Iterations);
        TestRemoting(proxy, Iterations);
        TestRemoting(proxy, Iterations);
        TestRemoting(proxy, Iterations);

        Console.ReadKey();
    }

    private static void TestRemoting(IRemote proxy, int iterations)
    {
        var start = DateTime.Now;

        for (var i = 0; i < iterations; i++)
        {
            proxy.Hello("Sergey");
        }

        var stop = DateTime.Now;

        Console.WriteLine("Remoting: {0} ms.", (stop - start).TotalMilliseconds);
    }
}

Here are the results: 结果如下:

Remoting: 261 ms.
Remoting: 224 ms.
Remoting: 252 ms.
Remoting: 243 ms.
Remoting: 234 ms.

As you can see, .Net Remoting is faster again. 如您所见,.Net Remoting再次更快。 The tests were ran outside the debugger. 测试是在调试器外部运行的。

Why is this so? 为什么会这样?

Debuggers are not real measure when try to compare the performance , here is what I did and got WCF Kicking out Remoting from the ring ;) 在尝试比较性能时,调试器不是真正的衡量标准,这是我所做的并且让WCF从环中踢出Remoting;)

1) Also modified your test to run it from same program/exe 1)还修改了你的测试,从同一个程序/ exe运行它

  namespace ConsoleApplication6
{
  [ServiceContract]
  internal interface IRemote
  {
    [OperationContract]
    string Hello(string name);
  }

  [ServiceBehavior]
  internal class Remote : MarshalByRefObject, IRemote
  {
    public string Hello(string name)
    {
      return string.Format("Hello, {0}!", name);
    }
  }

  class Program
  {
    private const int Iterations = 5000;

    static void Main(string[] p)
    {
      TestWcf();
      TestRemoting();
    }


    static void TestWcf()
    {
      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<IRemote>.CreateChannel(new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), new EndpointAddress(address));

      TestWcf(proxy, Iterations);
      TestWcf(proxy, Iterations);
      TestWcf(proxy, Iterations);
      TestWcf(proxy, Iterations);
      TestWcf(proxy, Iterations);

      Console.WriteLine("WCF done");

      host.Close();
    }

    private static void TestWcf(IRemote proxy, int iterations)
    {
      var start = DateTime.Now;

      for (var i = 0; i < iterations; i++)
      {
        proxy.Hello("Sergey");
      }

      var stop = DateTime.Now;

      Console.WriteLine("Wcf: {0} ms.", (stop - start).TotalMilliseconds);
    }

    static void TestRemoting()
    {
      var domain = AppDomain.CreateDomain("TestDomain");

      var proxy =
          (IRemote)
          domain.CreateInstanceFromAndUnwrap(Assembly.GetEntryAssembly().Location, "ConsoleApplication6.Remote");

      TestRemoting(proxy, Iterations);
      TestRemoting(proxy, Iterations);
      TestRemoting(proxy, Iterations);
      TestRemoting(proxy, Iterations);
      TestRemoting(proxy, Iterations);
      Console.WriteLine("Remoting done");
      Console.ReadKey();
    }

    private static void TestRemoting(IRemote proxy, int iterations)
    {
      var start = DateTime.Now;

      for (var i = 0; i < iterations; i++)
      {
        proxy.Hello("Sergey");
      }

      var stop = DateTime.Now;

      Console.WriteLine("Remoting: {0} ms.", (stop - start).TotalMilliseconds);
    }
  }

}

2) Compile it in release mode and ran it outside debugger. 2)在发布模式下编译它并在调试器外部运行它。

here is my output 这是我的输出 在此输入图像描述

If, in addition to SSamra's code, you move the creation of your host outside of your WCF test (since, in my opinion you should only be creating the host just once) you can get even faster responses: 如果除了SSamra的代码之外,还要在WCF测试之外移动主机的创建(因为,在我看来,您应该只创建一次主机),您可以获得更快的响应:

static void Main(string[] args)
{
    var address = "net.pipe://localhost/test";

    host = new ServiceHost(typeof(Remote));
    host.AddServiceEndpoint(typeof(IRemote), new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), address);
    host.Open();

    proxy = ChannelFactory<IRemote>.CreateChannel(new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), new EndpointAddress(address));

    TestWcf(Iterations);
    TestRemoting(Iterations);

    TestWcf(Iterations);
    TestRemoting(Iterations);

    TestWcf(Iterations);
    TestRemoting(Iterations);

    host.Close();

    Console.ReadKey();
}

Responses: 对策: 在此输入图像描述

This shows that, when configured like this, WCF in process is significantly faster than .Net remoting! 这表明,当这样配置时,WCF正在进行中明显快于.Net远程处理!

The MSDN article you refer to at the start of your question compares Remoting with WCF NetNamedPipes as an IPC mechanism (meaning Inter-Process Communication, not Intra-Process Communication). 您在问题开头引用的MSDN文章将远程处理与WCF NetNamedPipes比较为IPC机制(意味着进程间通信,而不是进程内通信)。 Your test code is comparing performance for communication within the same process. 您的测试代码正在比较同一过程中的通信性能。

It is my understanding that WCF's designers had a goal of substantially beating all pre-existing remoting technologies for performance, in all cross-network and cross-process scenarios, but not necessarily cross-domain within the same process. 我的理解是,WCF的设计人员的目标是在所有跨网络和跨进程场景中大幅击败所有预先存在的远程技术以实现性能,但不一定在同一进程中跨域。 In fact I think they have got fairly close to Remoting performance in the cross-domain scenario too, as other answerers have indicated. 事实上,我认为他们在跨域方案中的Remoting性能也非常接近,正如其他回答者所指出的那样。 But you should not be surprised if you don't get a performance gain from using WCF in this particular scenario. 但是,如果在这种特定情况下使用WCF无法获得性能提升,那么您不应该感到惊讶。

It is not a reason to doubt WCF's superior performance for Inter-Process Communication. 这并不是怀疑WCF在进程间通信方面的卓越性能的理由。

Wcf: 261,03 ms.
Wcf: 247,02 ms.
Wcf: 236,02 ms.
Wcf: 235,02 ms.
Wcf: 236,02 ms.

WCF NetNamedPipeBinding done. Avg : 243,02

Wcf: 508,05 ms.
Wcf: 467,05 ms.
Wcf: 484,05 ms.
Wcf: 458,05 ms.
Wcf: 458,05 ms.

WCF NetTcpBinding done. Avg : 475,05

Remoting: 35,00 ms.
Remoting: 58,01 ms.
Remoting: 35,00 ms.
Remoting: 35,00 ms.
Remoting: 34,00 ms.

Remoting done. Avg : 39,40

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM