JerryKur
JerryKur

Reputation: 7519

Is there a more efficient way to create lists that are the same?

I have a series of lists and classes that implement a table of data. The basic classes are: Columns, Rows, and Cells. The Rows contains some ID information and list of Cells which contains the row's value for each column. Currently I create the rows in a cell with code like this

void CreateRow()  
{  
    Row newRow = new Row();  
    newRow.ID = idInfo;  
    foreach (var Column in Columns)  
    {  
        newRow.Cells.Add(new Cell(Column.ID));  
    }  
    Rows.Add(newRow);  
}

The works fine, but in some cases am calling CreateRow() 20,000 times and have 200+ columns. So I am wondering if there is a more efficient way to populate the cells since the cells in a certain column in each row are identical.

Any ideas?

Thanks,

Jerry

Upvotes: 1

Views: 134

Answers (4)

Fred
Fred

Reputation: 185

You're creating the cells anyways. So I gather that the question refers to when you will fill the cells with their values, which are always in each column for all rows.

  1. I actually think that from a correctness point of view, it makes sense to have the data duplicated, since they are in effect separate instances of the same data.

  2. That said, if it is not really data, but you just want to show a view-column with the same value for each row, and you just want it as a data column in order to ease showing it as a view-column, then in your property-get Row.Cells(Id) you can check the ID, and if it's one of those columns where the value is always the same, return that value, bypassing looking up your _Cells collection.

  3. If the data is mostly the same and sometimes different, you may want to use 'default values' where if the Cell object does not exist, a default value for that column will be returned. This necessitates a GetValue() method on the row, though, if you want to avoid having the Cell object altogether for places where it is default.

  4. If you don't care about #1, you can really make a single instance of whatever the value is, and reference it in your Cell's value. This is harder to do for a Value Type than for a Reference Type (definition here) but it can be done.

  5. Lastly, is there any reason you're not using .NET's supplied DataTable and DataRow types? I'm sure the MS geeks programmed as much efficiency as they could into those.

Upvotes: 0

Jim
Jim

Reputation: 61

Some suggestions (depends on what you are looking for)

  • Consider using (strongly typed) DataSet/DataTable

  • If using List and you know the size, set the capacity to avoid reallocation (new List(2000))

  • Use struct instead of class if it makes sense

  • Cache objects if it makes sense (instead of duplicating the same object over and over)

Upvotes: 0

BrokenGlass
BrokenGlass

Reputation: 160852

Currently you create unique Cell object for each position in your matrix - that's a lot of cells given your use case of 20.000 + rows.

One approach to be more efficient could be to not add the cells at all when you construct the matrix, but only when you try to get or set its value (i.e using Lazy<T>).

Assuming you set the value of a cell before retrieving it, you could then have a factory method for creating a cell with a value - make the Cell object immutable and when you are "creating" a Cell for which you already have another cell with an identical value, return that cell instead. This could reduce the total number of Cell objects significantly, of course there's more overhead since you need to check whether you have a cell of the same value already and need to call the factory method again if you need to update the value of a cell.

Then again all of this could not be worth it if you do not experience any memory/performance problems with your current approach - measuring performance is key here.

Upvotes: 2

Chuck Savage
Chuck Savage

Reputation: 11945

Isn't Columns a collection?

var Ids = Columns.Select(c => c.Id).ToArray();
var Names = Columns.Select(c => c.Name).ToArray();

etc. Except why do that if Columns is already a collection? For you could do Columns[index].Id

Or if you must have the code you outlined:

Row newRow = new Row();  
newRow.ID = idInfo;  
// presuming Cells is a List<>
newRow.Cells.AddRange(Columns.Select(c => new Cell(c.Id)));
Rows.Add(newRow); 

Upvotes: 0

Related Questions