我试图最小化在同一台机器上跨AppDomain进行通信的性能损失.在我的玩具示例中,A类在AppDomain 1中加载.它创建一个AppDomain 2并在那里加载一个Class 2实例(Class 2继承自MarshalByRef)获取代理.然后,Class 1重复调用代理上不返回任何值的方法.
我得到以下结果:
虽然我理解2和3之间的性能损失(序列化),但我真的不明白为什么从案例1到案例2的速度要慢100倍.据我所知,一旦创建了代理,所有后续的方法调用必须非常快,因为没有数据从一个AppDomain编组到另一个AppDomain.现在有人为什么要通过AppDomains进行通信这么慢?难道我做错了什么?
PS1.我对这个唯一的技巧是在这里:"与跨越一个AppDomain边界的成本是令人尴尬的." 我猜他指的是序列化......
PS2.我不计算AppDomain或代理创建时间(我的基准测试从第一个方法调用开始)
PS3.我在WinXP SP3机器上使用.NET 3.5.我也试过.NET 4.0 Beta 1没有显着差异.
我正在使用委托从非托管代码调用托管代码.当我在默认的AppDomain中调用托管代码时,我每次调用的平均值为5.4ns.当我呼叫第二个AppDomain时,我每次呼叫的测量值为194ns.(默认VS2017 x86发布配置,不在调试器下运行).
调用不是默认的AppDomain时,为什么性能会低得多?由于我来自非托管方,它不了解AppDomains,我希望直接调用目标域.但是,性能打击意味着委托调用默认域然后编组到真实目标.我确实看到了UM2MDoADCallBack踩踏拆装的时候.它出现WrongAppDomain:在UMThunkStub.asm中
如何防止这种不必要的封送并直接调用特定的AppDomain?
我用来测试它的代码如下.
#pragma unmanaged
#include <wtypes.h>
#include <cstdint>
#include <cwchar>
typedef void (__stdcall *ManagedUpdatePtr)();
struct ProfileSample
{
static uint64_t frequency;
uint64_t startTick;
wchar_t* name;
int count;
ProfileSample(wchar_t* name_, int count_)
{
name = name_;
count = count_;
LARGE_INTEGER win32_startTick;
QueryPerformanceCounter(&win32_startTick);
startTick = win32_startTick.QuadPart;
}
~ProfileSample()
{
LARGE_INTEGER win32_endTick;
QueryPerformanceCounter(&win32_endTick);
uint64_t endTick = win32_endTick.QuadPart;
uint64_t deltaTicks = endTick - startTick;
double nanoseconds = (double) deltaTicks / (double) frequency * 1000000000.0 / count;
wchar_t …Run Code Online (Sandbox Code Playgroud)