У меня есть несколько сильно оптимизированных математических функций, выполнение которых занимает 1-2 nanoseconds
. Эти функции вызываются сотни миллионов раз в секунду, поэтому проблемы с вызовами вызывают беспокойство, несмотря на и без того отличную производительность.
Чтобы обеспечить возможность сопровождения программы, классы, предоставляющие эти методы, наследуют интерфейс IMathFunction
, так что другие объекты могут напрямую хранить определенную математическую функцию и использовать ее при необходимости.
public interface IMathFunction
{
double Calculate(double input);
double Derivate(double input);
}
public SomeObject
{
// Note: There are cases where this is mutable
private readonly IMathFunction mathFunction_;
public double SomeWork(double input, double step)
{
var f = mathFunction_.Calculate(input);
var dv = mathFunction_.Derivate(input);
return f - (dv * step);
}
}
Этот интерфейс вызывает огромные накладные расходы по сравнению с прямым вызовом из-за того, как его использует потребительский код. Прямой вызов занимает 1-2 нс, а вызов виртуального интерфейса - 8-9 нс. Очевидно, что наличие интерфейса и его последующая трансляция виртуального вызова является узким местом для этого сценария.
Я хотел бы сохранить и ремонтопригодность и производительность, если это возможно. Есть ли способ разрешить виртуальную функцию для прямого вызова, когда создается экземпляр объекта, чтобы все последующие вызовы могли избежать накладных расходов? Я предполагаю, что это будет связано с созданием делегатов с IL, но я не знаю, с чего начать.