Подтвердить что ты не робот

DataTable.Select vs DataTable.rows.Find vs foreach vs Find (Предикат <T>)/Лямбда

У меня есть DataTable/collection, который кэшируется в памяти, я хочу использовать это как источник для генерации результатов для автоматического полного текстового поля (с использованием AJAX, конечно). Я оцениваю различные варианты быстрого извлечения данных. Количество элементов в коллекции/строках в datatable может варьироваться от 10000 до 2 000 000. (Чтобы мы не отвлекались, на данный момент предполагаем, что решение принято, у меня достаточно ОЗУ, и я буду использовать кэш, а не запрос базы данных для этого)

У меня есть дополнительная бизнес-логика для этой обработки; Я должен определить приоритет для автоматического полного списка в соответствии с столбцом priority (int) в коллекции. Поэтому, если я кто-то ищет Micro, и я получаю 20 результатов слов/предложений, начинающихся с Micro, тогда я бы выбрал 10 лучших результирующих элементов с наивысшим приоритетом. (следовательно, необходимо иметь свойство приоритета, связанное со строковым значением).

Элементы коллекции уже отсортированы в алфавитном порядке.

Что было бы лучшим решением в этом случае.
1. Использование DataTable.Select(.
2. Использование DataTable.Rows.Find(.
3. используйте пользовательскую коллекцию с foreach или для повторения своих значений.
4. используйте общую коллекцию с анонимными делегатами или lambda (поскольку оба дают такую ​​же производительность или не?)

4b9b3361

Ответ 1

Графики не размещены в моей записи в блоге; более подробную информацию можно найти на http://msdn.microsoft.com/en-us/library/dd364983.aspx

Еще одна вещь, которую я с тех пор обнаружил, заключается в том, что для больших наборов данных использование целочисленного родового словаря выполняет невероятно хорошо. Это также помогает устранить многие проблемы, вызванные операциями сортировки, необходимыми для операций агрегации, такими как min и max (либо с DataTable.Compute, либо LINQ).

В "закодированном родовом словаре" я подразумеваю Dictionary(Of String, Dictionary(Of String, Dictionary(Of Integer, List(Of DataRow)))) или подобный метод, где ключ для каждого словаря является поисковым термином.

Конечно, это не будет полезно при любых обстоятельствах, но у меня есть хотя бы один сценарий, в котором реализация этого подхода приводит к улучшению производительности 500x.

В вашем случае я бы использовал простой словарь с первыми 1-5 символами, а затем List(Of String). Вам нужно будет создать этот словарь один раз, добавив слова в списки с первыми 1-5 символами, но после этого вы сможете получить невероятно быстрые результаты.

Обычно я обертываю такие вещи в классе, что позволяет мне делать такие вещи, как легко добавлять слова. Вы также можете использовать SortedList(Of String) для автоматического сортировки результатов. Таким образом, вы можете быстро найти список слов, соответствующих первым N символам, которые были напечатаны.

Ответ 2

На моем autocomplete, я сначала попытался использовать подход linq/lambda, производительность немного медленная. DataTable.Select быстрее, чем linq, поэтому я использую это. Я еще не сравнил производительность между DataTable.Select и datatable.Find

Ответ 3

Мы можем размышлять об этом весь день, но так как это не огромный фрагмент кода, почему бы не написать каждый из них и сравнить их друг с другом?

public delegate void TestProcedure();

public TimeSpan Benchmark(TestProcedure tp)
{
    int testBatchSize = 5;
    List<TimeSpan> results = new List<TimeSpan>();
    for(int i = 0; i<testBatchSize; i++)
    {
        DateTime start = DateTime.Now;
        tp();
        results.Add(DateTime.Now - start);
    }
    return results.Min();
}

Ответ 5

Как насчет DataView? Вы можете применить условие фильтрации и сортировать по приоритету и легко выполнить итерацию результатов, чтобы добавить к своим результатам.