Доброго времени суток, кто может объяснить следующее поведение
Стояла задача определить скорость вызова функций:
1. Внутри одного домена
2. Между доменами
3. Между процессами
В качестве теста замеряли вызов функции F с различными типами параметров:
class F(class)
int F(int)
class F(class, class, class, class, class)
int F(int, int, int, int, int)
struct F(struct, struct, struct, struct, struct)
Замеры делали для 100, 1 000 и 10 000 итераций. Здесь я приведу результаты среднего значения согласно данных для 100 итераций в миллисекундах:
Вид теста Внутри домена Между доменами Между процессами
class F(class) 31 37 375
int F(int) 16 26 219
class F(class, class, class, class, class) 47 42 2167
int F(int, int, int, int, int) 16 89 745
struct F(struct, struct, struct, struct, struct) 15 15 0 (*)
* — тесты не проводились, т.к. структуру нельзя вызвать из другого процесса, т.к. она не может быть унаследована от MarshalRefObject
Замечание: Последний вид теста (5) со структурами был осуществлен путем замены в 3-м тесте слова class на struct.
А теперь сам вопрос, как объяснить то, что при увеличении количества скалярных (int) параметров (см. тесты 2 и 4) происходит резкое снижение производительности, причем,
ТОЛЬКО при междоменном взаимодействии. При этом скорость падает настолько, что тест 3 начинает показывать более высокую скорость. Причем, мы проверяли и этот же эффект наблюдается не только для int, но и для long, bool, byte, double. А вот для структур такого эффекта нет!
Буду признателен за комментарии.
PS: метод в котором выполнялись тесты
string exeAssembly = Assembly.GetEntryAssembly().FullName;
AppDomain domain1 = AppDomain.CreateDomain("MyDomain1");
AppDomain domain2 = AppDomain.CreateDomain("MyDomain2");
ObjectHandle o = domain1.CreateInstance("IDoc", typeof(Class1).FullName);
ObjectHandle o2 = domain2.CreateInstance(exeAssembly, typeof(Module1).FullName);
Class1 c = (Class1)o.Unwrap();
Class1 c2 = (Class1)o.Unwrap();
Class1 c3 = (Class1)o.Unwrap();
Class1 c4 = (Class1)o.Unwrap();
Class1 c5 = (Class1)o.Unwrap();
Class2 domen2c2 = (Class2)o2.Unwrap();
for (int q = 0; q < 3; q++) {
int tick = Environment.TickCount;
for (int i = 0; i < Convert.ToInt32(maskedTextBox1.Text); i++) {
domen2c2.AddClass(c, c2, c3, с4, с5);
}
tick = Environment.TickCount - tick;
listBox1.Items.Add(tick.ToString());
}
listBox1.Items.Add("БЕЗ Маршалинга");
Class1 cla = new Class1();
Class1 cla2 = new Class1();
Class1 cla3 = new Class1();
Class1 cla4 = new Class1();
Class1 cla5 = new Class1();
for (int q = 0; q < 3; q++) {
int tick = Environment.TickCount;
for (int i = 0; i < Convert.ToInt32(maskedTextBox1.Text); i++) {
domen2c2.AddClass(cla, cla2, cla3, cla4, cla5);
}
tick = Environment.TickCount - tick;
listBox1.Items.Add(tick.ToString());
}
класс создаваемый во втором домене
[Serializable]
public class Class 2 : MarshalByRefObject {
private static int _name = 0;
public int AddInt(int name, int name2, int name3, int name4,int name5) {
_name += name;
return name;
}
public int AddInt(int name) {
_name += name;
return name;
}
public Class1 AddClass(Class1 cl, Class1 cl2, Class1 cl3, Class1 cl4, Class1 cl5) {
_name += cl.Count_;
return cl;
}
public Class1 AddClass(Class1 cl) {
_name += cl.Count_;
return cl;
}
}
класс создаваемый в первом домене
[Serializable]
public class Class1 : MarshalByRefObject {
public static int Count = 0;
public int AddScalar(int value) {
value += Count;
return value;
}
public int AddObject(int value) {
Count += value;
return Count;
}
public int Count_ {
get { return Count; }
}
public Class1 GetClass() {
return this;
}
}