流短[]比流式字节慢〜800倍[] - 如何加快速度?

时间:2016-08-30 13:57:15

标签: c# wcf

我在流媒体模式下使用WCF在进程之间传输一些大型short[]数组,而且我遇到了传输速度非常慢的问题。

我已经完成了一些测试,事实证明,传输short[]数组比使用包含相同字节数的byte[]数组慢大约800倍。

我认为我必须在这里做错事,因为这种行为是不可能的。

鉴于以下复制,有人可以建议我如何加快速度吗?

请注意,我使用的是流模式,因为数组非常大,使用非流模式似乎在传输过程中总共使用了数组大小的三倍。 (我在一个单独的进程中包装第三方32位托管DLL,以便可以通过WCF从64位C#程序调用它。)

这是服务器和客户端代码。这似乎很长,但它是我能想出的最短完整的复制品......

代码非常简单:WCF接口只有两个方法,一个采用short[]参数,另一个采用byte[]参数。我通过传递short[]byte[]来测试它,每个StopwatchITest包含相同数量的字节,并使用using System; using System.Diagnostics; using System.ServiceModel; using Shared; namespace Shared { [ServiceContract] interface ITest { [OperationContract] void ShortTest(short[] array); [OperationContract] void ByteTest(byte[] array); } } namespace Client { class Client { static void Main() { int arraySizeInBytes = 10 * 1024 * 1024; var binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None) { MaxReceivedMessageSize = 4*arraySizeInBytes + 1024, SendTimeout = TimeSpan.FromHours(1), // To allow debugging without timeouts. ReceiveTimeout = TimeSpan.FromHours(1), ReaderQuotas = {MaxArrayLength = 4*arraySizeInBytes + 1024}, TransferMode = TransferMode.Streamed }; var channelFactory = new ChannelFactory<ITest>(binding, "net.pipe://localhost/wcftest"); var proxy = channelFactory.CreateChannel(); short[] shorts = new short[arraySizeInBytes/sizeof(short)]; for (int i = 0; i < shorts.Length; ++i) // Touch entire array to ensure memory allocated. shorts[i] = 1; byte[] bytes = new byte[arraySizeInBytes]; for (int i = 0; i < bytes.Length; ++i) // Touch entire array to ensure memory allocated. bytes[i] = 1; Stopwatch sw = new Stopwatch(); while (true) { Console.WriteLine("Press <ENTER> to call ByteTest() and ShortTest()"); Console.ReadLine(); Console.WriteLine("Calling ByteTest()"); sw.Restart(); proxy.ByteTest(bytes); Console.WriteLine("ByteTest() took " + sw.Elapsed); Console.WriteLine("Calling ShortTest()"); sw.Restart(); proxy.ShortTest(shorts); Console.WriteLine("ShortTest() took " + sw.Elapsed); } } } } 来计算所需的时间。

为简化起见,我已将using System; using System.ServiceModel; using System.Threading; using Shared; namespace Shared { [ServiceContract] interface ITest { [OperationContract] void ShortTest(short[] array); [OperationContract] void ByteTest(byte[] array); } } namespace Server { [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] class Server : ITest { static void Main() { int arraySizeInBytes = 10 * 1024 * 1024; var binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None) { MaxReceivedMessageSize = 4*arraySizeInBytes + 1024, SendTimeout = TimeSpan.FromHours(1), // To allow debugging without timeouts. ReceiveTimeout = TimeSpan.FromHours(1), ReaderQuotas = {MaxArrayLength = 4*arraySizeInBytes + 1024 }, TransferMode = TransferMode.Streamed }; var serviceHost = new ServiceHost(new Server()); serviceHost.AddServiceEndpoint(typeof(ITest), binding, "net.pipe://localhost/wcftest"); serviceHost.Open(); Console.WriteLine("Server started. Close console to stop."); Thread.Sleep(TimeSpan.FromHours(10)); } public void ShortTest(short[] array) { Console.WriteLine("ShortTest() received array of size " + array.Length); } public void ByteTest(byte[] array) { Console.WriteLine("ByteTest() received array of size " + array.Length); } } } 接口的副本放入客户端和服务器源代码中,以避免使用第三个库 - 真正的代码正确执行。

这些只是控制台应用程序 - 您只需要以任何顺序编译和运行它们,然后在客户端应用程序中按Enter键运行测试。

另请注意,我使用.Net 4.6.2,但我与其他版本的结果相似。

客户端

Press <ENTER> to call ByteTest() and ShortTest()

Calling ByteTest()
ByteTest() took 00:00:00.0519079
Calling ShortTest()
ShortTest() took 00:00:41.9868413
Press <ENTER> to call ByteTest() and ShortTest()

Calling ByteTest()
ByteTest() took 00:00:00.0344547
Calling ShortTest()
ShortTest() took 00:00:41.4307394
Press <ENTER> to call ByteTest() and ShortTest()

服务器

short[]

我在系统上得到的结果如下:

byte[]

有没有人有任何想法如何加快request数据的传输?

目前,我希望自己只需将其转换为bytes,但这是最令人不满意的。

0 个答案:

没有答案