Some comments inline , maybe a remoting guru can give a better answer especially for the slowness of oneway.
-----Original Message----- From: Moderated discussion of advanced .NET topics. [mailto:ADVANCED-DOTNET@;DISCUSS.DEVELOP.COM]On Behalf Of Nicko Cadell Sent: Friday, 18 October 2002 2:38 AM To: [EMAIL PROTECTED] Subject: [ADVANCED-DOTNET] A performace comparison between the TCP and HTTP remoting channels. I have created a program (see below) that compares the tcp and http remoting channels. The results are very interesting and lead me to ask several questions: 1) Why is the tcp channel so much faster than the http channel? 3 times faster seems too good to be true. Because http needs to text encode binary data and then encclose it in tcp packets ( http sits on top of tcp) . If you are sending text data in big blocks the difference will be less but tcp will always be a ot faster. 2) Why is the [OneWay] method over the tcp channel slower than a method without [OneWay]? But using the http channel the [OneWay] method is 15% faster than non [OneWay]. Not really sure about http but tcp/ip works best with streaming and windowing. If you only allow 1 direction it may be waiting for an aknowlegment on each packet. Not good. Normally is sends streams of packets and just listends for the aknowledgemnet. 3) Why is the remoting across machines faster than just across process on the same machine? The difference is small, but I am running it on a dual processor machine so it should be able to keep up with my 100Mbps (2 half duplex hubs between the machines) network. This is often a problem on uni process machines as well- it is basically up to the network driver. I have seen good ones and very bad ones. The worst ones send the data on the network and wait for responses / timeouts. The best ones make sure the data does not even go to the wire. 4) Why is the [OneWay] method over the tcp channel so slow? 86.313 seconds! The regular method call only takes 4 seconds and running the same thing over the http channel only takes 10.297. There seems to be something very wrong with that, but I am able to repeat it again and again. Again maybe no streaming - this would depend on more detail of the one way implementation. The test program can be run in either client or server mode (one of each is required). The client can connect either locally or remotely to the server. One object type is exposed as a singleton over the tcp and http channels. Both channels are set to use the BinaryFormatter (the http channel defaults to the SoapFormatter, which is obviously slower). The client tests each object in turn, it times batches of 5000 tests, calling different methods: void RegularMethod(string) takes a string, examines it, and returns void. string RegularMethodReturn(string) takes a string, examines it, and returns a unique string. [OneWay] void OneWayMethod(string) takes a string, examines it, and returns void. It has the OneWayAttribute set. The client times the batch of 5000 calls and displays the time taken in seconds. The result of the RegularMethodReturn is stored in an ArrayList to ensure that it really does return the results. This would appear to add very minimal overhead. The hardware used to run the test was a pair of dual P3 533MHz running Win2000 and .NET runtime 1.0 retail (+SP2). The network connection was a 100Mbps half duplex. Running with the client and server on the same machine gives the following results: >TestChannels.exe -client Connecting to localhost Testing TCP Channel Done with RegularMethod batch! 4.047 Done with RegularMethodReturn batch! 4.157 Done with OneWay batch! 4.281 DONE Testing TCP Channel Testing HTTP Channel Done with RegularMethod batch! 14.579 Done with RegularMethodReturn batch! 15.046 Done with OneWay batch! 12.282 DONE Testing HTTP Channel Running with the client and server on separate machines gives the following results: >TestChannels.exe -client=isis Connecting to isis Testing TCP Channel Done with RegularMethod batch! 4 Done with RegularMethodReturn batch! 4.234 Done with OneWay batch! 86.313 DONE Testing TCP Channel Testing HTTP Channel Done with RegularMethod batch! 13.281 Done with RegularMethodReturn batch! 13.657 Done with OneWay batch! 10.297 DONE Testing HTTP Channel The code for the test program is: using System; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; namespace TestChannels { class Class1 { [MTAThread] static void Main(string[] args) { if (args.Length == 1) { if (string.Compare(args[0], "-client", true) == 0) { Client("localhost"); return; } else if (args[0].StartsWith("-client=")) { Client(args[0].Substring(args[0].IndexOf('=')+1)); return; } else if (string.Compare(args[0], "-server", true) == 0) { Server(); return; } } Console.WriteLine("Argument required [-client|-server]"); } // Start in Client mode. Connect to the server and run the Test static void Client(string host) { Console.WriteLine("Connecting to "+host); ChannelServices.RegisterChannel(new System.Runtime.Remoting.Channels.Tcp.TcpClientChannel("", new BinaryClientFormatterSinkProvider())); ChannelServices.RegisterChannel(new System.Runtime.Remoting.Channels.Http.HttpClientChannel("", new BinaryClientFormatterSinkProvider())); TestObject tcpObject = (TestObject)Activator.GetObject(typeof(TestObject), "tcp://"+host+":2525/TestObject.rem"); TestObject httpObject = (TestObject)Activator.GetObject(typeof(TestObject), "http://"+host+":8585/TestObject.rem"); Console.WriteLine("Testing TCP Channel"); ClientTest(tcpObject); Console.WriteLine("DONE Testing TCP Channel\n"); Console.WriteLine("Testing HTTP Channel"); ClientTest(httpObject); Console.WriteLine("DONE Testing HTTP Channel\n"); } const int WARMUP_SIZE=1000; const int BATCH_SIZE=5000; // Test the performace of the TestObject static void ClientTest(TestObject testObject) { // Warm up for(int item=0; item<WARMUP_SIZE; item++) { testObject.RegularMethod("Batch"+item); string strRet = testObject.RegularMethodReturn("Batch"+item); testObject.OneWayMethod("Batch"+item); } int start; int end; // Batch Reqular Methods start = Environment.TickCount; for(int item=0; item<BATCH_SIZE; item++) { testObject.RegularMethod("Batch"+item); } end = Environment.TickCount; Console.WriteLine("Done with RegularMethod batch! {0}", TimeSpan.FromMilliseconds(end - start).TotalSeconds); testObject.RegularMethod("BatchEnd"); // Batch Reqular Methods start = Environment.TickCount; System.Collections.ArrayList list = new System.Collections.ArrayList(BATCH_SIZE); for(int item=0; item<BATCH_SIZE; item++) { string strRet = testObject.RegularMethodReturn("Batch"+item); list.Add(strRet); } end = Environment.TickCount; Console.WriteLine("Done with RegularMethodReturn batch! {0}", TimeSpan.FromMilliseconds(end - start).TotalSeconds); testObject.RegularMethodReturn("BatchEnd"); // Batch One Way Methods start = Environment.TickCount; for(int item=0; item<BATCH_SIZE; item++) { testObject.OneWayMethod("Batch"+item); } end = Environment.TickCount; Console.WriteLine("Done with OneWay batch! {0}", TimeSpan.FromMilliseconds(end - start).TotalSeconds); testObject.OneWayMethod("BatchEnd"); } // Start in server mode. Serve the TestObject via tcp and http channels static void Server() { try { ChannelServices.RegisterChannel(new System.Runtime.Remoting.Channels.Tcp.TcpServerChannel("", 2525, new BinaryServerFormatterSinkProvider())); ChannelServices.RegisterChannel(new System.Runtime.Remoting.Channels.Http.HttpServerChannel("", 8585, new BinaryServerFormatterSinkProvider())); RemotingConfiguration.RegisterWellKnownServiceType(typeof(TestObject), "TestObject.rem", WellKnownObjectMode.Singleton); } catch(Exception e) { Console.WriteLine("Exception = " + e); return; } System.Console.WriteLine("Hit <enter> to exit server..."); System.Console.ReadLine(); } } public class TestObject : MarshalByRefObject { public int pingCount = 0; [System.Runtime.Remoting.Messaging.OneWay] public void OneWayMethod(String s) { if (s.StartsWith("BatchEnd")) { Console.WriteLine("OneWayMethod {0}", s); } } public String RegularMethodReturn(String s) { if (s.StartsWith("BatchEnd")) { Console.WriteLine("RegularMethod {0}", s); } return "foo" + (++pingCount); } public void RegularMethod(String s) { if (s.StartsWith("BatchEnd")) { Console.WriteLine("RegularMethod {0}", s); } } } } THE END You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com. You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com.