I am currently writing some code in C# and have decided, at one point, that for my specific case a composite pattern will be useful.
However, there is clearly a performance problem in my code once I start making a composite of multiple components.
I am struggling a bit to explain myself, so here is some simple code that will help.
class Interface IComponent
{
public double operation(double[] vector);
}
class Sum: IComponent
{
public double operation(double[] vector)
{
double sum = 0;
foreach(double dub in vector) sum += dub;
return sum;
}
}
class SquaredSum: IComponent
{
public double operation(double[] vector)
{
double sum = 0;
foreach(double dub in vector) sum += dub * dub;
return sum;
}
}
class Composite: IComponent
{
IComponent[] components;
public Composite(params IComponent[] components) this.components = components;
public double operation(double[] vector)
{
double sum = 0;
foreach(var component in components) sum += component.operation(vector);
return sum;
}
}
Now, if I make a new composite object of Sum and SquaredSum, the code will have to loop through the double array (vector) twice, once for the Sum instance and once for the SquaredSum instance. This is a serious problem once I'm looking at a million rows of data.
Ideally, I'd like my code to compile/act roughly like as if both the sum and squared sum are being calculated in the same loop. So I only have to loop through the vector once.
My Solution
The solution I can think of is to change IComponent to an abstract class as below.
abstract class Component
{
public abstract double TransformData(dub);
public double operation(double[] vector)
{
sum = 0;
foreach(double dub in vector) sum += TransformData(dub);
return sum;
}
}
class Composite: Component
{
Component[] components;
public Composite(params Component[] components) this.components = components;
public double operation(double[] vector)
{
double sum = 0;
foreach(double dub in vector)
{
foreach(var component in components) sum += component.TransformData(dub);
}
return sum;
}
}
This will allow the code to only iterate through the input array once.
My concern with my solution is that implementations of each Component will be reasonably abstract. Also, each component is limited to only making operations on the current double/object is passed into it (perhaps I want an operation on the next and previous element).
For example, implementing a component that calculates the mean would be impossible with my solution, which is not what I want.
Question
My question is, is there another magic OOP bullet to solve this problem efficiently?
I'm partially aware that LinQ may offer a nice solution but I don't know how.
Thank you.