1

I have a simple question, why would I use an array of a single class over a class with multiple property arrays?

Context: I have a series of calculators that extend off a base calculator. Each calculator is intended to calculate the same things but in different ways. Here is the simplified base class (pay attention to the use of Flows):

public abstract class BaseCalculator : ICalculator
    {
        public Flows Flows { get; private set; }

        protected double[] BaseCurve { get; private set; }
        protected double CurrentBalance { get; private set; }
        protected int CurrentPeriod { get; private set; }

        public BaseCalculator(int periodLength, double[] baseCurve, double currentBalance)
        {
            Cashflows = new Flows(periodLength);
            BaseCurve = baseCurve;
            CurrentBalance = currentBalance;
        }

        //no default implementation will suffice
        protected abstract void CalcOne();
        protected abstract void CalcTwo();

        //many calcs do not implement
        protected virtual void CalcThree() {  }

        public ICalculator SetPeriod(int period)
        {
            CurrentPeriod = period;
            return this;
        }

        public virtual void Calculate()
        {
            //order matters
            CalcOne();
            CalcTwo();
            CalcThree();
            CalcFour();
        }

        protected virtual void CalcFour() => Flows.FlowFour[CurrentPeriod] = CurrentBalance + Flows.FlowTwo[CurrendPeriod] * BaseCurve[CurrentPeriod];

There is a list of 10 values each calculator must compute, these 10 values are calculated for n periods. Right now I have a class that contains a property array for each one of these values. NOTE: these properties can rely on one another in the calculator as seen above. Here is a trimmed down example class:

  public class Flows
    {
        public Flows(int periodLength)
        {
            FlowOne = new double[periodLength];
            FlowTwo = new double[periodLength];
            FlowThree = new double[periodLength];
            FlowFour = new double[periodLength];
        }

        public double[] FlowOne { get; private set; }
        public double[] FlowTwo{ get; private set; }
        public double[] FlowThree { get; private set; }
        public double[] FlowFour { get; private set; }
    }

So is there any reason why the above class would be less favorable than an array of the below class in my use case? I chose the above option because I assign values to these "Flows" at different times plus they do rely on one another.

public class Flow
    {
        public Flow() {}

        public double FlowOne { get; set; }
        public double FlowTwo{ get; set; }
        public double FlowThree { get; set; }
        public double FlowFour { get; set; }
    }

use in base calculator: public Flow[] Flows { get; private set; }

3 Answers 3

3

You've spoken to structure of the internal implementation.

You've spoken to internal clients — i.e. computing four from two and base at the same index.

But, what does the external client want to see?  Make the external interface so that the external consuming client gets the best abstraction, where the best abstraction is dealing with the fewest entities.  If there is a "pairing" of one thru four that the client wants to use, then provide that — otherwise the consuming client will have to deal with 4 sets of independent items that are conceptually related (but not formally in the code).

Once you have the external interface for the simplicity of the consuming clients, the implementation details aren't really that important.

3

There are advantages and disadvantages to both designs. If Flow one to four are related, it's only natural to group those four together and the vast majority of programmers will expect this design. On the other hand, it looks like your Calc... methods are only looking at them independently, so maybe they aren't as related as the name may suggest? Another advantage of having four separate arrays of doubles is that it's a lot more cache efficient (which probably doesn't matter unless you have megabytes or gigabytes of them). If you're not sure which one to take, provide both:

  public class Flows
    {
        public Flows(int periodLength)
        {
            FlowOne = new double[periodLength];
            FlowTwo = new double[periodLength];
            FlowThree = new double[periodLength];
            FlowFour = new double[periodLength];
        }

        public double[] FlowOne { get; private set; }
        public double[] FlowTwo{ get; private set; }
        public double[] FlowThree { get; private set; }
        public double[] FlowFour { get; private set; }
        public Flow this[int index] => new Flow(FlowOne[index], 
                                                FlowTwo[index],
                                                FlowThree[index],
                                                FlowFour[index]);
    }
2

I would like to add that this is related to Structure of arrays vs Arrays of structures.

Array of structures (AoS) is generally more intuitive and easy to use.

Structure of Arrays (SoA) has an advantage for processing with SIMD, since it is often easier/faster to process multiple items in parallel, than trying to process multiple properties of an item in parallel.

1
  • +1 for putting a name to these for me... it allows me to research further. Jul 16, 2021 at 15:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.