WCF与.Net Remoting

时间:2011-11-08 18:47:32

标签: c# wcf named-pipes .net-remoting

根据this article,带有命名管道的WCF是IPC的最佳选择,它比.Net Remoting快25%左右。

我有以下代码将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获得了5000次迭代的以下结果:

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

在此测试中,Wcf比.Net Remoting慢约7倍。

我试图:

  • 将安全模式设置为None;
  • 将InstanceContextMode设置为Single / PerCall;
  • 将ConcurrencyMode设置为Single / Multiple;

但结果是一样的。

有人知道我做错了什么吗?为什么WCF这么慢?

有没有办法加快这段代码?

提前致谢。

修改

我已经修改了一点测试。合同是一样的。

第一个测试看起来像这样(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);
    }
}

结果如下:

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

第二个测试看起来像这样(.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);
    }
}

结果如下:

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

如您所见,.Net Remoting再次更快。测试是在调试器外部运行的。

为什么会这样?

4 个答案:

答案 0 :(得分:23)

调试器在尝试比较性能时并不是真正的衡量标准,这是我所做的并且让WCF从环中踢出Remoting;)

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)在发布模式下编译并在调试器外运行。

这是我的输出 enter image description here

答案 1 :(得分:11)

如果除了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();
}

对策: enter image description here

这表明,当这样配置时,正在进行的WCF明显快于.Net远程处理!

答案 2 :(得分:4)

您在问题开头引用的MSDN文章将远程处理与WCF NetNamedPipes比较为 IPC 机制(意味着进程间通信,而不是进程内通信)。您的测试代码正在比较同一过程中的通信性能。

据我了解,WCF的设计人员的目标是在所有跨网络和跨进程场景中大幅击败所有预先存在的性能远程技术,但不一定在同一进程中跨域。事实上,我认为他们在跨域方案中的Remoting性能也非常接近,正如其他回答者所指出的那样。但是,如果在这种特定情况下使用WCF无法获得性能提升,那么您不应该感到惊讶。

这并不是怀疑WCF在进程间通信方面的卓越表现的理由。

答案 3 :(得分:0)

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