2016-02-24 2 views
6

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

Я бы хотел услышать от экспертов, может ли этот код воспользоваться Linq или другим методом, и если да, то каким образом?

Dim array_of_strings As String() 

    ' now I add strings to my array, these come from external file(s). 
    ' This does not take long 

' Throughout the execution of my program, I need to validate millions 
' of other strings. 

    Dim search_string As String 
    Dim indx As Integer 

    ' So we get million of situation like this, where I need to find out 
' where in the array I can find a duplicate of this exact string 

    search_string = "the_string_search_for" 

    indx = array_of_strings.ToList().IndexOf(search_string) 

Каждая из строк в моем массиве уникальна, без дубликатов.

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

+3

Почему вы вызываете 'ToList()'? Вы должны иметь возможность просто делать 'indx = array_of_strings.IndexOf (search_string)'. –

+1

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

+0

создание временного списка «миллионы раз» - может быть, это должен быть список? – Plutonix

ответ

5

Нет необходимости использовать Linq. Если вы использовали индексированную структуру данных, такую ​​как словарь, поиск будет представлять собой O (log n), за счет немного более длительного процесса заполнения структуры. Но вы делаете это один раз, затем делаете миллион поисков, вы собираетесь выйти вперед.

Смотрите описание словаря на этом сайте: https://msdn.microsoft.com/en-us/library/7y3x785f(v=vs.110).aspx

С (я думаю), вы говорите о коллекции, которая является его собственным ключом, вы можете сэкономить память, используя SortedSet<T> https://msdn.microsoft.com/en-us/library/dd412070(v=vs.110).aspx

+0

Я рассмотрю это. Любые указатели на то, как сделать быстрое исправление для вышеуказанного кода? – Yeahson

+0

Я сделал это с помощью словаря, но это замедляло процесс. Я еще не использовал 'SortedSet'. У меня мои данные отсортированы по-другому, что помогает в дальнейшей обработке, это логический порядок в отношении местоположения XY, поэтому потерять это было бы жалко. – Yeahson

+0

Итак, вы говорите, что обмен массивом строк для словаря вызвал общее снижение производительности? Я был бы очень удивлен этим. Либо не так много данных, как вы говорите, или нагрузка намного меньше запросов. Алгоритмический анализ Big-O - очень старая область информатики (потому что этот материал часто имел значение). –

0

Нет, я не думаю, что это может выиграть от linq. Запросы Linq медленны, относительно говоря. Однако вы можете попробовать использовать многопоточность.

+1

«Запросы Linq медленны» по сравнению с чем? Как многопоточная помощь? –

+0

Они медленны по сравнению с использованием linq. Все мои тесты показывают эти результаты. Вы когда-нибудь делали какие-либо сравнения? Мне интересно видеть результаты других людей. – RoyalPotato

+1

Многопоточность может помочь в поиске половины массива в одном потоке, а другая половина в другом потоке. Это уже снижает скорость выполнения. – RoyalPotato

0

Вы можете попробовать использовать DataTable, что, кажется, очень быстро здесь:

void Main() 
{ 
    var dt = new DataTable(); 
    dt.Columns.Add("foo", typeof(string));  
    dt.Columns.Add("bar", typeof(string)); 
    dt.Columns[0].Unique = true; 

    dt.Rows.Add("baz", "baaz"); 
    dt.Rows.Add("qux", "quux"); 

    // add one million rows 
    for (var i = 0; i < 1000000; i++) 
    { 
     dt.Rows.Add((i*2).ToString(), i); 
    } 

    var sw = Stopwatch.StartNew(); 
    // select some arbitrary value 
    var results = dt.Select("foo = '513916'"); 
    // get its index 
    dt.Rows.IndexOf(results.First()).Dump("Row index"); 
    sw.Stop(); 
    sw.Dump("Elapsed"); 
} 

Elapsed

(я не могу перевести его в VB)

+0

@ t3 спасибо, попробуем! – Yeahson

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