Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h2>The Notes</h2> <p>For the most part, the time is spent setting up and tearing down the WCF channel. The other lions share of time appears to be consumed by running within a debugger. Keep in mind this is really informal type testing.. :)</p> <p>I was able to reproduce your numbers, so i started from there. This showed WCF numbers were <strong>roughly 3xs greater than</strong> the remoting numbers.</p> <p>By caching the channel factory (and respective remoting objects), the numbers dropped so that WCF <strong>was only 2x's greater than</strong> the remoting numbers. </p> <p>After trying a dozen other different tweaks, the only one that seemed to shave any real measurable time off the numbers was to clear all the debug service behaviors (added by default) - this resulted in roughly ~100ms. Not enough to really get excited about.</p> <p>Then, on a whim, I <strong>ran the code outside the debugger, in a release configuration</strong>. The numbers dropped to <strong>roughly the equivalent of the remoting numbers, if not better</strong>. Forehead smacked the desk and called it done.</p> <p><strong>In a nutshell, you should see roughly the same, with a possibility of better performance using WCF and gain a better programming model to boot.</strong> </p> <h2>Sample Run</h2> <pre><code>remoting 1 test run in 347ms wcf 1 test run in 1544ms remoting 2 test run in 493ms wcf 2 test run in 324ms remoting 3 test run in 497ms wcf 3 test run in 336ms remoting 4 test run in 449ms wcf 4 test run in 289ms remoting 5 test run in 448ms wcf 5 test run in 284ms remoting 6 test run in 447ms wcf 6 test run in 282ms remoting 7 test run in 439ms wcf 7 test run in 281ms remoting 8 test run in 441ms wcf 8 test run in 278ms remoting 9 test run in 441ms wcf 9 test run in 278ms remoting 10 test run in 438ms wcf 10 test run in 286ms </code></pre> <h2>The Code</h2> <p>Note - this code has been completely bastardized. I apologize. :)</p> <pre><code>using System; using System.ServiceModel; using System.Runtime.Serialization; [ServiceContract] interface IWorkerObject { [OperationContract] Outcome DoWork(Input t); } [DataContract] [Serializable] class Input { [DataMember] public int TaskId { get; set; } [DataMember] public int ParentTaskId { get; set; } [DataMember] public DateTime DateCreated { get; set; } [DataMember] public string TextData { get; set; } [DataMember] public byte[] BinaryData { get; set; } } [DataContract] [Serializable] class Outcome { [DataMember] public string Result { get; set; } [DataMember] public string TextData { get; set; } [DataMember] public byte[] BinaryData { get; set; } } class Program { static AppDomain dom = AppDomain.CreateDomain("wcf domain", null); static WorkerObject dcnt = dom.CreateInstanceFromAndUnwrap(System.Reflection.Assembly.GetExecutingAssembly().Location, typeof(WorkerObject).FullName) as WorkerObject; static ChannelFactory&lt;IWorkerObject&gt; fact = new ChannelFactory&lt;IWorkerObject&gt;(new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), "net.pipe://localhost/the_channel"); static IWorkerObject chan = fact.CreateChannel(); static AppDomain remdom = AppDomain.CreateDomain("remoting domain", null); static IWorkerObject remoteObject; static void Main(string[] args) { remoteObject = remdom.CreateInstanceFromAndUnwrap(System.Reflection.Assembly.GetExecutingAssembly().Location, typeof(WorkerObject).FullName) as IWorkerObject; dcnt.OpenChannel(); int numberOfIterations = 10; for (int i = 1; i &lt;= numberOfIterations; i++) { run_rem_test(i); run_wcf_test(i); } fact.Close(); dcnt.CloseChannel(); AppDomain.Unload(dom); AppDomain.Unload(remdom); } static void run_rem_test(int iteration) { RunTest("remoting " + iteration, remoteObject); } static void run_wcf_test(int iteration) { RunTest("wcf " + iteration, chan); } static void RunTest(string test, IWorkerObject dom) { var t = new Input() { TextData = new string('a', 8192), BinaryData = null, DateCreated = DateTime.Now, TaskId = 12345, ParentTaskId = 12344, }; var sw = System.Diagnostics.Stopwatch.StartNew(); for (var i = 0; i &lt; 1000; i++) dom.DoWork(t); sw.Stop(); Console.WriteLine("{1} test run in {0}ms", sw.ElapsedMilliseconds, test); } } [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] class WorkerObject : MarshalByRefObject, IWorkerObject { ServiceHost m_host; public void OpenChannel() { m_host = new ServiceHost(typeof(WorkerObject)); m_host.AddServiceEndpoint(typeof(IWorkerObject), new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), "net.pipe://localhost/the_channel"); // cache our ServiceBehaviorAttribute, clear all other behaviors (mainly debug) // and add our ServiceBehavior back // var b = m_host.Description.Behaviors[0] as ServiceBehaviorAttribute; m_host.Description.Behaviors.Clear(); m_host.Description.Behaviors.Add(b); m_host.Open(); } public void CloseChannel() { m_host.Close(); } public Outcome DoWork(Input t) { return new Outcome() { TextData = new string('b', 8192), BinaryData = new byte[1024], Result = "the result", }; } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload