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.

Reply via email to