What is the minimum Cross AppDomain communication

2020-02-11 17:38发布

问题:

I am trying to minimize the performance penalty of communicating across AppDomains in the same machine. In my toy example, Class A is loaded in AppDomain 1. It creates an AppDomain 2 and loads there an instance of Class 2 (Class 2 inherits from MarshalByRef) getting back a proxy. Then Class 1 calls repeatedly a method on the proxy that returns no values.

I get the following results:

  1. No AppDomains, both classes are loaded in the same AppDomain and the first calls repetedly the method on the second (the method has no parameters): 24 million method calls/sec
  2. Two AppDomain as described above, method has no parameters or "bleeding" string parameters: 340.000 methods calls/sec
  3. Two AppDomains as described above, one serializable parameter (array of two strings): 64.000 method calls/sec

Although I understand the performance penalty between 2 and 3 (serialization), I really don't understand why I am 100 times slower from case 1 to case 2. To my understanding, once the proxy is created all subsequent method invocations must be really fast since no data are being marshalled from one AppDomain to the other. Does anybody now why communicating across AppDomains is so slow? Am I doing something wrong?

PS1. The only tip that I have on this is here: "And the cost of crossing an AppDomain boundary is embarrassing.". I was guessing he refers to serialization...

PS2. I don't count the AppDomain or Proxy creation time (my benchmarks start in the first method invocation)

PS3. I am using .NET 3.5 in a WinXP SP3 machine. I also tried .NET 4.0 Beta 1 with no significant differences.

回答1:

If you count lines of IL involved in each scenario, you will see that the CLR is doing much more than 100 times the work when remoting. A direct invocation is just a few opcodes, but with remoting there are multiple classes involved, real/transparent proxies, security checks, serialization, yadda yadda yadda. You will need to address this through design - there is no magic bullet for improving perf through implementation.



回答2:

Is there any way you can call a single helper method that takes parameters about how many times you want to call the method you need? Cross-AppDomain call performance varies greatly by implementation. I believe it could be significantly better in the CLR 4.0, but I'm not fully versed on the details there.

Generally though, you want to avoid the overhead by "batching" the calls through a helper method.



回答3:

I have seen the same results. I can't explain why it is so much slower, except that it is faster then having two different processes running and communicating with each other. In my design I was faced with a similar dilemma. At the end, I have modified my design to create independent app domains; the app domain was able to do its job without the need to communicate with another app domain during execution... It would only report data when completed.