Насколько это возможно, я хочу избежать ненужного дублирования кода. В моем сценарии, описанном ниже, я использовал Action
делегатов, чтобы избежать дублирования кода. Однако при использовании подхода Action
делегата код становится медленнее примерно на 50–80 %.
Есть ли более эффективный подход с точки зрения производительности, чем делегаты Action
, чтобы избежать дублирования кода в сценарии, описанном ниже?
У меня есть два метода, которые эквивалентны, за исключением самого внутреннего оператора длинного цикла:
public T[] MethodA<T>(T[] from)
{
...
for (var i = 0; i < len; ++i)
{
var j = GetIndex(i);
to[j] = from[i]; // This statement differs in MethodA and MethodB
}
...
return to;
}
public T[] MethodB<T>(T[] from)
{
...
for (var i = 0; i < len; ++i)
{
var j = GetIndex(i);
to[i] = from[j]; // This statement differs in MethodA and MethodB
}
...
return to;
}
Чтобы избежать дублирования кода, я реализовал вспомогательный метод, который принимает делегат Action
. Вызов делегата заменяет оператор переменной, например:
private T[] HelperMethod<T>(T[], Action<T[], T[], int, int> action)
{
...
for (var i = 0; i < len; ++i)
{
var j = GetIndex(i);
action(from, to, i, j); // Invoke the Action delegate
}
...
return to;
}
Затем я могу уменьшить MethodA
и MethodB
следующим образом:
public T[] MethodA<T>(T[] from)
{
return HelperMethod(from, (src, dest, src_idx, dest_idx) => dest[dest_idx] = src[src_idx]);
}
public T[] MethodB<T>(T[] from)
{
return HelperMethod(from, (src, dest, dest_idx, src_idx) => dest[dest_idx] = src[src_idx]);
}
Обратите внимание, что единственная разница между рефакторингом MethodA
и MethodB
заключается в порядке следования src_idx
и dest_idx
в сигнатурах Action
вызовов HelperMethod
.
if
сразу за пределы цикла и просто продублировать содержимое цикла... Что-то среднее. - person Rawling   schedule 22.03.2012if
должен быть внутри цикла, чтобы максимально избежать дублирования. В любом случае спасибо, Роулинг. - person Anders Gustafsson   schedule 22.03.2012