Anders Gustafsson
Anders Gustafsson

Reputation: 15981

Is there a more efficient approach than C# Action delegates for avoiding this code duplication?

As much as possible I want to avoid unnecessary duplication of code. In my scenario described below I have used Action delegates to avoid code duplication. However, when using the Action delegate approach, the code becomes approximately 50%-80% slower.

Is there a more efficient approach from a performance perspective than Action delegates to avoid code duplication in the scenario described below?

I have two methods that are equivalent except for the innermost statement of a lengthy loop:

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;
}

To avoid code duplication I have implemented a helper method that takes an Action delegate. Invocation of the delegate replaces the variable statement, like this:

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;
}

Then I can reduce MethodA and MethodB as follows:

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]);
}

Note that the only difference between the refactored MethodA and MethodB is the order of the src_idx and dest_idx in the Action signatures of the HelperMethod calls.

Upvotes: 4

Views: 360

Answers (1)

demoncodemonkey
demoncodemonkey

Reputation: 11957

You could pass a parameter to the method and do A or B depending on the parameter.
I don't like it but I'm just saying it could be done. I actually prefer the Action way.

Upvotes: 1

Related Questions