2016-02-12 3 views
3

У меня есть коллекция объектов, и я бы хотел получить все объекты, у которых одно из свойств соответствует строке поиска. До сих пор я пробовал несколько методов фильтрации, а именно List.ForAll, IEnumerable.Where и ParallelQuery.Where.Самый быстрый способ фильтрации коллекции C#

List<Foo> cache = GetAllObjs(); // source list containing lots of objects 

Вариант 1:

List<Foo> foos = cache.AsParallel().Where(x => x.Name == "bar").ToList(); 

Вариант 2:

List<Foo> foos = cache.Where(x => x.Name == "bar").ToList(); 

Вариант 3:

List<Foo> foos = cache.FindAll(x => x.Name == "bar"); 

Поскольку ParallelQuery.Where использует несколько ядер, то, как представляется, быстрое решение. Кроме этого, существуют ли другие методы фильтрации, такие как использование разных типов коллекций или функции фильтрации? Исходная коллекция не обязательно должна быть списком.

+4

[Гонка лошадей] (http://ericlippert.com/2012/12/17/performance-rant/) ... возможно, это зависит от размера массива и других факторов. – Sayse

+0

Я гонялся за лошадьми. .. Три, о которых я мог подумать. Мне было интересно, есть ли у меня разные лошади, которые могли бы участвовать в гонке ... – painiyff

+0

Сложно сказать, какой лучший вариант (из данного) был бы, как я сказал, для меньших массивов/списков, время разворота параллельные потоки могут не принести никакой пользы с точки зрения времени выполнения. вызов 'ToList' может не понадобиться либо – Sayse

ответ

8

Помимо этого, существуют ли другие способы фильтрации, такие как использование различных типов коллекций или функции фильтрации?

Если у вас есть несколько объектов с тем же именем, вы можете использовать Lookup<string, Foo>. Вы можете думать о качестве поиска string -> List<Foo> словаря:

// create 
var foosByName = GetAllObjs().ToLookup(x => x.Name, x => x); 

// search 
var barFoos = foosByName["bar"].ToList(); 

Конечно, если есть только один Foo для каждого имени, классический Dictionary<string, Foo> будет служить.

Поиск в словаре или поиске - это (обычно) операция O (1), тогда как методы поиска в вашем вопросе - O (n).

+2

. О, я изменил на' Lookup ' и сделал поиск почти мгновенным. Поскольку мне приходилось выполнять подстроку, как в 'x.Name.Contains (" bar ")', мне пришлось создать 'Lookup' с индексом как все возможные подстроки' Name'. На этапе препроцесса он многому увлекся, но сам поиск был молниеносно. – painiyff

+1

@painiyff: Рад это услышать. Если вам нужно что-то с поддержкой поддержки памяти с низким потреблением памяти * и *, вы можете [использовать trie (sic) или двоичный поиск через SortedDictionary] (http://stackoverflow.com/q/1902108/87698). – Heinzi

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