0

I have the following code from MSDN sample:

if (sheetData.Elements<Row>().Where(r => r.RowIndex == rowIndex).Count() != 0)
{
    row = sheetData.Elements<Row>().Where(r => r.RowIndex == rowIndex).First();
...

Which I refactored as follows:

Dictionary<uint, Row> rowDic = sheetData.Elements<Row>().ToDictionary(r => r.RowIndex.Value);
if (rowDic[rowIndex].Count() != 0)
{
    row = rowDic[rowIndex];
...

Now, I sensed that if the Enumerable.ToDictionary<> method actually has to enumerate through all the data, then this would be as well redundant, but the MSDN documentation does not say anything about how this conversion takes place.

The alternative I'm thinking of using is:

var foundRow = sheetData.Elements<Row>().Where(r => r.RowIndex == rowIndex);
if (foundRow.Count() != 0)
{
    row = foundRow.First();
...

However, I would like to know from possibly previous experiences which would be faster and why.

Thanks.

Chibueze Opata
  • 9,856
  • 7
  • 42
  • 65
  • *What* would be redundant? It's not really clear what you're asking. But `ToDictionary` *does* iterate through the whole input sequence, eagerly. – Jon Skeet May 08 '13 at 13:48
  • If you want to know which of two things is faster then **run them** and you'll soon find out. – Eric Lippert May 08 '13 at 15:01

2 Answers2

5

The cleaner alternative is:

var row = sheetData.Elements<Row>()
                   .FirstOrDefault(r => r.RowIndex == rowIndex);
if (row != null)
{
    // Use row
}

That will only iterate through the sequence once, and it will stop as soon as it finds a match.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

Both the .Count() and ToDictionary methods have to enumerate all elements to obtain the result.

Here's the most efficient implementation:

var foundRow = sheetData.Elements<Row>().FirstOrDefault(r => r.RowIndex == rowIndex);
if (foundRow != null)
{
    row = foundRow;

...
jeroenh
  • 26,362
  • 10
  • 73
  • 104