views:

372

answers:

6

Here is how it looks generally:

I get values from an outside device and I have to store a timestamp with them. Somehow I want to store the info in an efficient way to make my life easier when it comes to processing all the stuff.

As a simple solution I have created a class which stores one row:

public class X 
{
  public DateTime timestamp;
  public double value1;
  public double value2;
}

And then I create a List out of these objects.

Can you show a better way of dealing with this kind of data?

Thanks!

A: 

What is wrong with this solution? It looks fine to me.

Do you have a specific problem that this representation is causing you problems with?

Jon Grant
A: 

This type is small enough that, assuming it is immutable, you may like to consider using a struct. This will reduce the load on the garbage collected heap.

What exactly are you trying to optimise? Memory footprint? Read performance? How will you be reading the data?

Drew Noakes
+4  A: 

That seems perfectly reasonable to me, although I'd use properties rather than public fields. If you're fetching values from an external device, you may want to consider making the type immutable - pass all the values into the constructor and store them in readonly fields. I find it easier to reason about my code when the types are immutable :)

What sort of efficiency are you concerned about? How many of these values will you have? Even though there aren't many values here, I'd probably still use a class instead of a struct... I very rarely create my own structs. Again, I just find classes easier to reason about (no need to worry about boxing, for example.) Also, this feels like "a collection of values" rather than one indivisible value which is what structs are usually used for (numbers etc). It just doesn't feel like a struct to me.

You will incur an overhead per object, but I wouldn't worry about that unless you have a really good reason to.

EDIT: This seems a trivial point to make, but give everything meaningful names. For example:

public class DeviceReading
{
    private readonly DateTime timeStamp;
    public DateTime TimeStamp { get { return timeStamp; } }

    private readonly double temperature;
    public double Temperature { get { return temperature; } }

    private readonly double airPressure;
    public double AirPressure { get { return airPressure; } }

    public DeviceReading (DateTime timeStamp,
                          double temperature,
                          double airPressure)
    {
        this.timeStamp = timeStamp;
        this.temperature = temperature;
        this.airPressure = airPressure;
    }
}

I suspect you'd do so anyway, but I just thought I'd make sure :)

A couple of other things to consider:

  • Assuming you're using a fairly recent version of .NET, you might want to use DateTimeOffset rather than DateTime. The benefit is that DateTiemOffset unambiguously represents an instant in time, whereas DateTime can be UTC, local or unspecified.

  • Depending on the kind of readings you're taking (and how they're communicated) you may want to use decimal instead of double. Probably not for temperature and air pressure (or any other "physical" values) but if you're dealing with artificial values like money, decimal is your friend. Given that this is reading from a device, you're probably dealing with physical quantities, but I thought it worth mentioning.

  • For dealing with the collections of readings, you really want to look into LINQ. It's lovely :)

Jon Skeet
I won't have too many objects, just a few thousand. Mainly, I am trying to optimize for readability and "writeability", the more easier it is to deal with the data structure, the better. Speed and memory footprint are not issues currently.
Richard J. Terrell
Right. In that case I'd definitely stick with a class (fewer corner cases to worry about) and use a `List<T>` for the collection.
Jon Skeet
What is the purpose of declaring the private fields readonly aswell as only using getters for the public properties? Is the getter not enough alone?
James
A: 

If you plan to put many X object in an array, I suggest making it a struct since it holds just a few "plain old data" items (no objects). Other than that, it seems like a straightforward way to work with the data.

280Z28
A: 

There is nothing particularly wrong with the way you are already doing it. (Although as others have suggested, you should be making your fields private and using public properties instead)

Often the best way to decide upon what storage structure to use is to consider how you will be using the data.

For example, if you know you need to process the data in some kind of order, consider a SortedList instead. If you know you need direct access to the data from some kind of key or index, use a Dictionary.

Simon P Stevens
A: 

Why not just create a table class that maintains a list of X (rows)?

public class X
{
     private double val1;
     private double val2;
     private DateTime stamp;

     public X(double value1, double value2)
     {
          this.val1 = value1;
          this.val2 = value2;
          this.stamp = DateTime.Now;
     }

     public double Value1 { get { return this.val1; } }
     public double Value2 { get { return this.val2; } }
     public DateTime TimeStamp { get { return this.stamp; } }
}

public class XTable
{
     private List<X> rows;
     public XTable(List<X> rows)
     {
         this.rows = rows;
     }

     public XTable()
     {
         this.rows = new List<X>();
     }

     public List<X> Rows { get { return this.rows; } }
}
James
What value does `XTable` give over just using a `List<X>` directly? It seems to be adding an extra level of indirection/complexity for no benefit.
Jon Skeet
Just incase he perhaps wants to add some other methods for controlling/manipulating the list e.g. querying.
James
For querying, I'd just use LINQ instead. I would *definitely* only start coming up with a custom collection type if and when it provides real value, rather than speculatively.
Jon Skeet
Yeah I would also use LINQ, but the methods must be defined somewhere, so surely the best option would be to place them in a class where they would be most appropriate. However, I do agree I would only use it if there was an absolute must for it, also makes it a little nicer to store a list of Table classes that have rows rather than a list of a list of rows that are supposed to represent a table...
James
Which methods must be defined somewhere? If you just need to perform a query, I'd do that query in the code that needs the results, not in a table class which doesn't really need anything else. If you need a list of tables, then it *may* make sense to aggregate those, but each table could just be a list of the appropriate row type...
Jon Skeet
The methods for querying the lists if they are required. My normal precedent is to delegate code out to controller/helper classes if they require extra functionality. Otherwise, yes the Lists themselves would be sufficient.
James