2016-02-24 24 views
6

Ho questo codice, che funziona bene, ma è lento su dataset di grandi dimensioni.può migliorare il mio codice dall'uso di LINQ?

Mi piacerebbe sapere dagli esperti se questo codice potrebbe trarre vantaggio dall'uso di Linq o da un altro metodo e, in caso affermativo, come?

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) 

Ognuna delle stringhe nel mio array è univoca, senza duplicati.

Questo funziona abbastanza bene, ma come ho detto, troppo lento per i set di dati più grandi. Sto eseguendo questa query milioni di volte. Attualmente ci vogliono circa 1 minuto per un milione di query, ma questo è troppo lento per i miei gusti.

+3

Perché stai chiamando 'ToList()'? Dovresti essere in grado di fare semplicemente 'indx = array_of_strings.IndexOf (search_string)'. –

+1

In ogni caso se vuoi vedere dove il tuo codice è lento prendi un profiler decente e misuralo. Linq non ha lo scopo di migliorare le prestazioni, ma ha lo scopo di migliorare la produttività riducendo il numero di loop da codificare. –

+0

creazione di una lista temporanea "milioni di volte" - forse dovrebbe essere una lista? – Plutonix

risposta

5

Non è necessario utilizzare Linq. Se si utilizzava una struttura di dati indicizzata come un dizionario, la ricerca sarebbe O (log n), al costo di un processo leggermente più lungo di riempimento della struttura. Ma lo fai una volta, poi fai un milione di ricerche, uscirai in anticipo.

vedere la descrizione del dizionario in questo sito: https://msdn.microsoft.com/en-us/library/7y3x785f(v=vs.110).aspx

Dato (credo) si sta parlando di una collezione che è la propria chiave, si potrebbe risparmiare un po 'di memoria utilizzando SortedSet<T> https://msdn.microsoft.com/en-us/library/dd412070(v=vs.110).aspx

+0

Lo esaminerò. Qualche suggerimento su come fare una soluzione rapida per il codice sopra? – Yeahson

+0

L'ho fatto con 'dictionary', ma questo ha rallentato il processo. Non ho ancora usato un 'SortedSet'. Ho ordinato i miei dati in un altro modo che aiuta l'ulteriore elaborazione, è un ordine logico per quanto riguarda la posizione XY, quindi perdere sarebbe un peccato. – Yeahson

+0

Quindi, stai dicendo che lo scambio dell'array di stringhe per un dizionario ha causato un calo generale delle prestazioni? Ne sarei abbastanza sorpreso. O non ci sono tanti dati quanti dici, o il carico di lavoro è molto meno ricerche. Big-O L'analisi algoritmica è una vecchia area dell'informatica (perché questa roba era molto importante). –

0

No, non penso che possa beneficiare di linq. Le query di Linq sono lente, relativamente parlando. Si potrebbe provare a multithread, tuttavia.

+1

"Le query di Linq sono lente" rispetto a cosa? Come potrebbe aiutare il multithreading? –

+0

Sono lenti rispetto a non usare linq. Tutti i miei test mostrano questi risultati. Hai mai fatto paragoni tuoi? Sono interessato a vedere i risultati degli altri. – RoyalPotato

+1

Il multithreading può essere utile cercando metà dell'array in un thread e l'altra metà in un altro thread. Ciò riduce già la velocità di esecuzione. – RoyalPotato

0

Si potrebbe provare a utilizzare un DataTable che sembra essere molto veloce qui:

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

(Non riesco a tradurlo in VB)

+0

@ t3 grazie, ci proveremo! – Yeahson

Problemi correlati