[VB 2010] utilizzo di linq
-
venerdì 13 aprile 2012 14:40
ciao a tutti,
ho iniziato da poco ad usare linq e questa è la prima volta che riesco ad utilizzarlo senza problemi.premetto che ho letto varie dispense riguardanti linq.comunque la mia domanda è la seguente...
date le seguenti procedure, perchè quella che utilizza linq è molto piu lenta? c'è qualcosa che sbaglio??
funzione normale: 5.8s
procedura con utilizzo linq: 12.3s
Private Function GoodFalseCallsRealError() As String Dim TotCallFalseCalls As Integer = 0 Dim TotCallRealErrors As Integer = 0 Dim TotCalNotClassified As Integer = 0 Dim TotCalAlignmentError As Integer = 0 Dim TotCallFail As Integer = 0 Dim ArrayGood As New List(Of String) Dim ArrayFail As New List(Of String) For r = 0 To dbgTabella.RowCount - 1 Select Case dbgTabella(mResult, r).Value.ToString Case mGood 'good If Not ArrayFail.Contains(dbgTabella(mSerialNumber, r).Value.ToString) Then ArrayGood.Add(dbgTabella(mSerialNumber, r).Value.ToString) End If Case mFalseCall If ArrayGood.Contains(dbgTabella(mSerialNumber, r).Value.ToString) Then ArrayGood.Remove(dbgTabella(mSerialNumber, r).Value.ToString) End If If Not ArrayFail.Contains(dbgTabella(mSerialNumber, r).Value.ToString) Then ArrayFail.Add(dbgTabella(mSerialNumber, r).Value.ToString) End If TotCallFalseCalls += 1 Case mRealErrors If ArrayGood.Contains(dbgTabella(mSerialNumber, r).Value.ToString) Then ArrayGood.Remove(dbgTabella(mSerialNumber, r).Value.ToString) End If If Not ArrayFail.Contains(dbgTabella(mSerialNumber, r).Value.ToString) Then ArrayFail.Add(dbgTabella(mSerialNumber, r).Value.ToString) End If TotCallRealErrors += 1 Case mNotClassified If ArrayGood.Contains(dbgTabella(mSerialNumber, r).Value.ToString) Then ArrayGood.Remove(dbgTabella(mSerialNumber, r).Value.ToString) End If If Not ArrayFail.Contains(dbgTabella(mSerialNumber, r).Value.ToString) Then ArrayFail.Add(dbgTabella(mSerialNumber, r).Value.ToString) End If TotCalNotClassified += 1 Case mAlignmentError If ArrayGood.Contains(dbgTabella(mSerialNumber, r).Value.ToString) Then ArrayGood.Remove(dbgTabella(mSerialNumber, r).Value.ToString) End If If Not ArrayFail.Contains(dbgTabella(mSerialNumber, r).Value.ToString) Then ArrayFail.Add(dbgTabella(mSerialNumber, r).Value.ToString) End If TotCalAlignmentError += 1 Case mFail If ArrayGood.Contains(dbgTabella(mSerialNumber, r).Value.ToString) Then ArrayGood.Remove(dbgTabella(mSerialNumber, r).Value.ToString) End If If Not ArrayFail.Contains(dbgTabella(mSerialNumber, r).Value.ToString) Then ArrayFail.Add(dbgTabella(mSerialNumber, r).Value.ToString) End If TotCallFail += 1 End Select Next Return ArrayGood.Count.ToString & ";" & TotCallFalseCalls.ToString & ";" & TotCallRealErrors.ToString & ";" & TotCalNotClassified.ToString & ";" & TotCalAlignmentError.ToString & ";" & TotCallFail.ToString & ";" & ArrayFail.Count.ToString End Function Private Sub ProvaToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ProvaToolStripMenuItem.Click Dim TotCallFalseCalls As Integer = 0 Dim TotCallRealErrors As Integer = 0 Dim TotCalNotClassified As Integer = 0 Dim TotCalAlignmentError As Integer = 0 Dim TotCallFail As Integer = 0 Dim ArrayGood As New List(Of String) Dim ArrayFail As New List(Of String) Dim seriale As String = String.Empty For r = 0 To dbgTabella.RowCount - 1 seriale = dbgTabella(mSerialNumber, r).Value.ToString Select Case dbgTabella(mResult, r).Value.ToString Case mGood Dim risp = (From serial As String In ArrayGood Where serial = seriale Select serial).Count If risp = 0 Then ArrayGood.Add(seriale) End If Case mFalseCall, mRealErrors, mNotClassified, mAlignmentError, mFail Dim risp = (From serial As String In ArrayGood Where serial = seriale Select serial).Count If risp > 0 Then ArrayGood.Remove(seriale) End If risp = (From serial As String In ArrayFail Where serial = seriale Select serial).Count If risp = 0 Then ArrayFail.Add(seriale) End If Select Case dbgTabella(mResult, r).Value.ToString Case mGood 'good Case mFalseCall TotCallFalseCalls += 1 Case mRealErrors TotCallRealErrors += 1 Case mNotClassified TotCalNotClassified += 1 Case mAlignmentError TotCalAlignmentError += 1 Case mFail TotCallFail += 1 End Select End Select Next Console.WriteLine(ArrayGood.Count.ToString & ";" & TotCallFalseCalls.ToString & ";" & TotCallRealErrors.ToString & ";" & TotCalNotClassified.ToString & ";" & TotCalAlignmentError.ToString & ";" & TotCallFail.ToString & ";" & ArrayFail.Count.ToString) End Sub- Modificato X-SL4UGHT3R lunedì 16 aprile 2012 06:34
- Spostato Irina TurcuMicrosoft Contingent Staff, Owner lunedì 30 aprile 2012 03:20 Topic più adatto per il forum dedicato a LINQ. (Da:Microsoft Visual Basic Forum)
Tutte le risposte
-
lunedì 30 aprile 2012 03:21Proprietario
Ciao X-SL4AUGHT3R,
Per miglior supporto, ti ho spostato la domanda sul forum dedicato a LINQ.
Saluti,
Irina Turcu - Microsoft
[Manifesto] Regole e Aspetti generali all'uso dei forum MSDN
Questo contenuto è distribuito “as is” e non implica alcuna responsabilità da parte di Microsoft. L'azienda offre questo servizio gratuitamente, allo scopo di aiutare gli utenti e approfondire la loro conoscenza dei prodotti e tecnologie Microsoft.
-
lunedì 30 aprile 2012 09:42
ciao
il discorso è complesso :)
le query linq vengono eseguite ma prima precompilate, quindi in alcuni scenari potrebbero essere meno performanti di un codice procedurale, ma non credo sia il tuo caso
il tuo caso è poco performante perchè stai approcciando in maniera procedurale l'uso di linq che è invece funzionale
e poi il .Count su di una collection la materializza e conteggia e quindi è proprio poco performante
sostituisci i vari .Count con magari un .FirstOrDefault(tua where) == null
oppure una .All(tua where) che torna già un boolean
dovresti poi evitare di usare dbgTabella e enumerare a mano sulla Row, prova a lavorare direttamente sul suo DataSource che è sicuramente una collezione o qualcosa di simile facilmente enumerabile ad oggetti sempre tramite LINQ
il consiglio finale: LINQ come già detto serve per fare una query, cerca di cambiare radicalmente la tua logica in ottica di farti dare direttamente il risultato da un'unica macro query, al posto di iterare a mano con i vari For e fare .Add e .Remove di lentissime liste
restiamo a disposizione per ogni dubbio
a presto
- Contrassegnato come risposta Irina TurcuMicrosoft Contingent Staff, Owner domenica 13 maggio 2012 02:55




