2008-10-09 2 views
0

Что обычно происходит при чтении/сравнении информации о строках из DataTable?.NET Самый быстрый способ перебора строк в datatable?

'assume dt as datatable' 

'method 1' 
dim i as int32 
for i = 0 to dt.rows.count - 1 
    .... 
next 

'method 2' 
dim row as datarow 
for each row in dt.rows 
    .... 
next 

И если есть разница, в каких обстоятельствах он платит за использование одного над другим?

Заранее благодарим за любые указания!

ответ

6

Компилятор расширяет для каждого короткий цикл.

for each row in dt.rows 
// expands to: 
IEnumerator e = dt.rows.GetEnumerator() 
while e.MoveNext() 
    row = e.Current 

Таким образом, вы платите небольшое количество накладных расходов. Но для ясности я все равно придерживаюсь For Every, если вы работаете только в одной строке, и вы не изменяете набор данных.

2

В действительности нет разницы. Хотя вы технически оплачиваете небольшую цену в методе foreach, для перехода через интерфейс IEnumerable.

+1

Да, в моей тестовой упряжи два метода только показывают разницу в производительности после около 100K итераций. – StingyJack 2008-10-23 11:56:10

3

У второго был бы небольшой штраф. Однако, что касается обстоятельств, я прочно использовал метод 2 для ясности кода. Тем не менее, я бы использовал метод 1, если мне когда-либо понадобится сделать что-то вроде доступа к следующей/предыдущей строке при анализе текущей строки.

1

@ gdean232 is right - почти никакой разницы вообще. Если производительность является проблемой, использование SqlDataReader вместо этого заметно быстрее.

-2

Реализация foreach на самом деле немного быстрее, чем стандарт для реализации, поскольку каждый доступ к массиву индексов должен быть ограничен. Однако, поскольку идиомы:

for(int i =0; i < myArray.Count; ++i) 
{ 
    // do something with myArray[i]; 
} 

является общим, то компилятор ищет его как частный случай и оптимизирует его, поэтому он становится быстрее. Однако любое небольшое отклонение от этого формата (например, int len ​​= MyArray.Count; for (int i = 0; i < len; ++ i)) не будет распознано и будет использовать более медленный код.

2

Ну, есть разница, поскольку GetEnumerator и MoveNext, которые вызывают в foreach-loop, являются виртуальными (вызов требует прохождения указателя) и, следовательно, не может быть встроен. Эти накладные расходы на самом деле малы, если вы не делаете лот петель.

В некоторых случаях, хотя компилятор заменит foreach на for-loop (я верю при повторении массивов).

Я лично предпочитаю foreach в моем коде ASP.NET MVC для ясности, как многие говорили здесь, но часто используют for-loop тоже. Джо Даффи недавно опубликовал интересную статью о стоимости перечисляя http://joeduffyblog.com/2008/09/21/the-cost-of-enumerating-in-net/

Смежные вопросы