2012-06-07 2 views
1
public class User 
{ 
    public int Id { get; set; } 
    public int Age { get; set; } 
    public string Name { get; set; } 
} 

У меня есть пользователей 100 тыс. Пользователей.Несколько полей Индексированный массив объектов

Запрос: Получить Пользователи, чье имя "Рафаэль" И чей возраст составляет от 40 до 50

  • По Linq2Objects:. Users.Where (р => р Название == "Рафаэль" & & р. Возраст> = 40 & & p.Age < = 50) .ToArray();

Есть ли альтернативная реализация с лучшей производительностью? (Readonly поточно-)

(мультииндексированные Пользователи Array)

Я проверил его производительность. Для пользователей 1000 тыс. Требуется 30-50 мс. Кажется, это не важно, но это так. Потому что я могу получить 50 запросов за секунду.

С решением dharnitski. Требуется 0 мс. :)

Но есть ли какие-либо рамки кода, которые делают это прозрачно.

public class FastArray<T> 
+0

По потокобезопасным, вы имеете в виду, что будут выполняться другие процессы, записывающие вашу коллекцию, когда вы запрашиваете ее? –

+0

Не жалко. ReadOnly ThreadSafe. Я обновил вопрос. – ozz

+0

_Но есть ли какая-либо инфраструктура кода делает ее прозрачной. - Да. Это RDBMS :) –

ответ

4

Вы не можете получить желаемый результат без полного сканирования набора данных, если ваши данные не подготовлены. Предварительно подготовьте данные, когда время не критично, и работайте со отсортированными данными, когда вам нужно короткое время отклика.

В мире баз данных есть аналогия.

Существует таблица со 100 тыс. Записей. Кто-то хочет запустить запрос Select с предложением where, которое фильтрует данные, а не первичный ключ. Это всегда будет медленная операция «сканирование таблицы» в плане выполнения, если не реализованы индексы (индексы).

Пример кода, который реализует индексацию с помощью ILookup<TKey, TValue>:

//not sorted array of users - raw data 
User[] originalUsers; 
//Prepare data in advance (create one index). 
//Field with the best distribution should be used as key 
ILookup<string, User> preparedUsers = originalUsers.ToLookup(u => u.Name, u => u); 


//run this code when you need subset 
//search by key is optimized by .NET class 
//"where" clause works with small set of data 
preparedUsers["Rafael"].Where(p=> p.Age>=40 && p.Age<=50).ToArray(); 

Этот код не является столь мощным, как индексы базы данных (например, он не поддерживает подстроки), но он показывает эту идею.

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