@daniil14056

Почему вызов функции по адресу медленнее (delegate*)0x3232332299060u чем простой делегат?

Развлекаюсь тестируя разные извращения.
Вот такой простой код, который генерит, код, который подставит прямой адрес функции
Я не могу, посмотреть ассемблер сгенерированного кода, но представляю что там одна инструкция перехода с абсолютным адресом. Тогда как вызов по делегату, это вычисление адреса перед вызовом.
И предполагаю что будет быстрее, а она медленее в 10 раз. В 10 раз как так,(при этом работает)
((delegate*<void>)0x3232332299060u)();  // псевдокод 
 c->action();

Почему первый способ работает в 3-10 раз медленнее?

//;#  ((delegate*<void>)0x3232332299060u)();
        IL_0000: ldc.i8 883059002544224
        IL_0009: conv.u
        IL_000a: calli void()
// инструкций меньше,  есть константы, значит типа должно быть быстрее, но почему нетак

//;#   c->action(); 
        IL_000f: ldarg.0
        IL_0010: ldind.ref
        IL_0011: ldfld class [System.Runtime]System.Action C::action
        IL_0016: callvirt instance void [System.Runtime]System.Action::Invoke()
        IL_001b: ret

Код который творит такую ересь
void createSafe(Env*e){ 
             //  тут к примеру вообще вызов по делегату, что ну уж точно медленнее должно быть
            var dm = new DynamicMethod("_1", null, new Type[] { typeof(Env).MakePointerType() });
            var il = dm.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, GetSafeHandlerField()); 
            il.Emit(OpCodes.Callvirt, typeof(Action).GetMethod("Invoke", Type.EmptyTypes)); 
            il.Emit(OpCodes.Ret);
            return dm.CreateDelegate<EnvHandler>();

 }
unsafe void createUnsafe(Env*e){  
            var dm = new DynamicMethod("_1", null, new Type[] { typeof(Env).MakePointerType() });
            var il = dm.GetILGenerator(); 
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldc_I8, typeof(Env).GetMethod("IncStatic").MethodHandle.GetFunctionPointer() ); 
            il.EmitCalli(OpCodes.Calli, CallingConvention.Cdecl, null, new Type[] { typeof(Env*) });
            il.Emit(OpCodes.Ret);
            return dm.CreateDelegate<EnvHandler>();
}
struct Env{  
  int A;
  static public unsafe void IncStatic(Env*e)
 {
     e->A++;
 }
 public Func<Env*> action=IncStatic; 
}

При том разница в 10 раз!!!!!!!!!
Я предположу, что среда CLR не оптимизирует, не инлайнит, когда видит адрес в не пойми куда. или вообще там когда видит такой адрес, начинает проверять.
Ни где инфы не нашел.
(игрался со всеми конвенциями вызовов, и разным способом получения адреса функции, всегда медленнее)
  • Вопрос задан
  • 86 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы