Linq к объектам очень медленный по сравнению с dataview - PullRequest
3 голосов
/ 06 сентября 2011

Я большой поклонник Linq для печати, ясности и краткости.Но я нахожу очень медленным поиск соответствующих записей по сравнению со старым просмотром данных в 2000 раз!

Я пишу приложение для резервного копирования больших наборов файлов - 500 000 файлов и 500 ГБданные.Я создал манифест файлов в наборе резервных копий и сравнил файлы в каталоге с файлами в манифесте, документирующими то, что уже было скопировано.Таким образом, я знаю, какие файлы были изменены, и поэтому их необходимо скопировать.

Медленный шаг такой:

var matchingMEs = from m in manifest where m.FullName == fi.FullName select m;

, где manifest = List<ManifestEntry> и ManifestEntry является относительно простым POCO.

Общая производительность составляет 17-18 записей в секунду.

При использовании просмотра данных:

DataView vueManifest = new DataView(dt, "", "FullName", DataViewRowState.CurrentRows);

затем в цикле найдите соответствующие записи манифеста с .FindRows:

matchingMEs = vueManifest.FindRows(fi.FullName);

... тогда я получаю около 35 000 файлов в секунду пропускной способности!

Это нормально?Я не могу поверить, что Linq приходит по такой цене.Это Linq или объекты, которые замедляют процесс?

(кстати, я попытался использовать Dictionary и SortedList, а также List<ManifestEntries>, и все они дали примерно одинаковый результат.)

1 Ответ

1 голос
/ 06 сентября 2011

Ваш DataView сортирует по полному имени, и, следовательно, FindRows может переходить прямо к правильным записям, в то время как ваш запрос linq должен выполнять итерации по списку, пока не достигнет правильных записей.Это определенно будет заметно, если у вас есть 500 000 записей.

Если полное имя уникально, то, когда вы переключаетесь на использование словаря, я бы заподозрил, что вы все еще просматриваете его, используя аналогичный запрос linq, что-то вроде

var matchingME = (from m in manifest where m.Key == fi.FullName select m).Single();

тогда как вы должны использовать

var matchingME = manifest[fi.FullName] ;
...