Announcement

Collapse
No announcement yet.

Effizientes Suchen in List(of T) Objekten

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Effizientes Suchen in List(of T) Objekten

    Hallo!

    Ich bin auf der Suche nach einem effizienten Verfahren, um Informationen x-mal abzufragen.

    Ich habe eine SQL-Tabelle mit 5 Feldern und 500 DS, die ich in meinem Programm mehrere Millionen-mal, nach einem bestimmten Wert abfragen muss.
    (where Feld1=a and Feld2=b and Feld3=c and Feld4>= DatumX).

    Meine Ansätze:
    1. Ein DataTable Objekt mit DataView und Filter.

    2. Ein List(of T) Objekte und IComparable Implementierung mit einer CompareTo Function.

    3. Abfrage mit LINQ.

    Welche ist die schnellste Methode, bzw. gibt es noch schnellere Alternativen?

  • #2
    die ich in meinem Programm mehrere Millionen-mal
    Die Informationen programmseitig auslesen und zur Verfügung stellen. Bei Änderung in der DB sind diese zu aktualisieren
    Christian

    Comment


    • #3
      Hallo Christian!

      Die Frage ist ja, wie ist der schnellste Zugriff.
      Dass die Informationen zur Verfügung gestellt werden ist ja klar und wird ja mit entweder mit einem Dataset (DataView) oder einer List(of T) Klasse mit ICompareable oder mit LINQ gemacht.

      Auszug der List(of T) Klasse:
      Code:
      Public Class VerrHSNS
          Implements IComparable(Of VerrHSNS)
      
          Private Shared ListHSNS As New List(Of VerrHSNS)
          Private Shared _vGes As Integer
          Private Shared _gGes As Integer
          Private Shared _kpnr As Integer
          Private Shared _von As Date
      
          Public hns_kpnr As Integer = 0                          'Personengruppennummer kpnr
          Public hns_von As Date = New Date(1900, 1, 1, 0, 0, 0)  'Saision von
          Public hns_bis As Date = New Date(1900, 1, 1, 0, 0, 0)  'Saison bis
          Public hns_gefGesell As Integer = 0                        'gilt für diese Gefahrene Gesellschaft
          Public hns_verkGesell As Integer = 0                        'gilt für die verkaufende Gesellschaft
          Public hns_BewFak As Double = 0.0                       'BewertungsFaktor
      
          Public Sub New()
          End Sub
      
          Public Sub New(ByVal verrDL As VerrDAL, ByVal vt As VerrTyp)
              HSNSInit(verrDL, vt)
          End Sub
      
          Private Sub HSNSInit(ByVal verrDL As VerrDAL, ByVal vt As VerrTyp)
              Dim obj As VerrHSNS
              Dim sqlDR1 As SqlDataReader
              Dim sqlCmd As SqlCommand
      
              Try
                  sqlCmd = verrDL.GetCmd()
                  sqlCmd.CommandText = DefaultValues.csqlVerrHSNS
                  sqlCmd.Parameters.Clear()
                  sqlCmd.Parameters.Add("@verrKonfigID", SqlDbType.Int, 0).Value = vt.verr_konfigID
                  sqlDR1 = sqlCmd.ExecuteReader()
                  While sqlDR1.Read()
                      obj = New VerrHSNS
                      obj.hns_kpnr = CType(sqlDR1("hns_kpnr"), Int32)
                      obj.hns_von = CType(sqlDR1("hns_von"), Date)
                      obj.hns_bis = CType(sqlDR1("hns_bis"), Date)
                      obj.hns_verkGesell = CType(sqlDR1("hns_verkGesell"), Int32)
                      obj.hns_gefGesell = CType(sqlDR1("hns_gefGesell"), Int32)
                      obj.hns_BewFak = CType(sqlDR1("hns_BewFak"), Double)
                      VerrHSNS.ListHSNS.Add(obj)
                  End While
                  VerrHSNS.ListHSNS.Sort()
      
              Catch ex As Exception
                  Throw New Exception
              Finally
                  If sqlDR1 IsNot Nothing Then sqlDR1.Close()
              End Try
      
      
          End Sub
      
      '''LINQ Version
          Public ReadOnly Property FindMe1(ByVal pverkGes As Integer, ByVal pgefGes As Integer, _
                                      ByVal pkpnr As Integer, ByVal pdatum As Date) As Double
      
              Get
                  'Dim obj As New VerrHSNS
                  'Dim index As Integer
                  Try
      
                      Dim vRet = (From o In ListHSNS _
                                  Where o.hns_verkGesell = pverkGes And o.hns_gefGesell = pgefGes And o.hns_kpnr = pkpnr _
                                 And pdatum >= o.hns_von Order By o.hns_von Descending Select New With {o.hns_BewFak}).First()
      
                      Return vRet.hns_BewFak
      
                  Catch ex As Exception
                  End Try
      
                  Return 1.0
      
              End Get
      
          End Property
      
      '''FindIndex Version
          Public Function FindMe2(ByVal pverkGes As Integer, ByVal pgefGes As Integer, _
                            ByVal pkpnr As Integer, ByVal pvondatum As Date) As Double
              _vGes = pverkGes
              _gGes = pgefGes
              _kpnr = pkpnr
              _von = pvondatum
      
              Dim index = VerrHSNS.ListHSNS.FindIndex(AddressOf FindMeObj)
              If index >= 0 Then
                  Return VerrHSNS.ListHSNS(index).hns_BewFak
              End If
              Return 1.0
      
      
          End Function
      
      
      
          Private Shared Function FindMeObj(ByVal o As VerrHSNS) As Boolean
      
              ' AndAlso prevents evaluation of the second Boolean
              ' expression if the string is so short that an error
              ' would occur.
              If o.hns_verkGesell = _vGes AndAlso o.hns_gefGesell = _gGes AndAlso o.hns_kpnr = _kpnr AndAlso _von >= o.hns_von Then
                  Return True
              Else
                  Return False
              End If
          End Function
      
      .....

      Comment


      • #4
        Wenn ich die Informationen mehrere Millionen mal zu Verfügung stellen müsste, würde ich diese einmal aus der DB lesen und diese dann programmatisch (nicht mehr über die DB) zur Verfügung stellen. Über eine Singelton-Klasse u.a.
        Christian

        Comment


        • #5
          Wieviele verschiedene Suchmöglichkeiten hast du denn und sind die Treffer eindeutig oder gibts multiple Treffer? Wenn es nur eine Handvoll würde ich entsprechend viele Sortierte Liste nehmen.

          Konkret N SortedList's mit generiertem Key aus den Suchparametern. Über den Key(der ist in einer SortedList indiziert und damit schnell ist) hast du dann direkten Zugriff auf deine TrefferKlasse.

          Comment


          • #6
            meine idee:
            vorausgesetzt es sollen auch andere nutzer auf die DB schauen und du willst, dass alle nuzter IMMER die aktuellsten daten haben...

            eine einzelne dbTabelle machen mit 1 spalte 1 zeile...
            da kommt ein datum zur aktualisierung rein.

            dies wird nur geändert, wenn sich ein datensatz auf der DB wirklich ändert...


            nun liest du deine db mit den 500DS aus und speicherst die in einer ArrayList, oder sonstwo wo du es magst.
            nun kannst du programmseitig diese arraylist durchgehen ohne eine einzige DB abfrage zu starten, was das ganze schneller machen sollte...

            und bei jeder abfrage dieser arraylist fragst du erst die db ab, ob sich etwas aktualisiert hat, wenn nicht, ist deine arraylist auf dem neusten stand...
            wenn doch einfach wieder die komplette tabelle auslesen und wieder im client durchgehen.


            ich weis allerdings nicht, ob mir andere bei diesem vorgehen zustimmen würden :-)

            MFG Nooa

            Comment


            • #7
              Ich weiß nicht, ob deine Lösung passt. Aber dieser Satz stört mich gewaltig:
              Originally posted by Nooa View Post
              ... speicherst die in einer ArrayList, oder sonstwo wo du es magst...
              ArrayList gehört auf den Schrottplatz; der Themenstarter hat doch selbst schon von List(of T) gesprochen - das ist 1000mal besser.

              Jürgen

              Comment


              • #8
                wenn er dich so gewalltig stört, ist das doch der breiten gesellschaft eigl. egal oder?

                es war ein vorschlag!
                und wenn er wie du richtig festgestellt hast eine List(of T) verwenden möchte, kann er dies auch tun!

                ...
                dass die leute den ganzen tag nichts besseres zu tun haben als posts zu kritisieren nervt mich total!
                statt ma sinvolle lösungen und lösungswege vorzubringen!

                Comment


                • #9
                  OK, du hast Pech gehabt, dass ich dich gerade zweimal korrigieren musste. Aber das hat nichts damit zu tun, dass ich nichts Besseres zu tun hätte und/oder jede Kleinigkeit kritisieren will. Aber ArrayList kann und darf ich nicht als sinnvoll stehenlassen (und das ist nicht nur meine Überzeugung):

                  ArrayList ist eine Liste von Objekten, nämlich Instanzen der Klasse object. Alles, was herausgeholt werden soll, muss erst in den richtigen Typ konvertiert werden. Wenn es ein falscher Typ ist, knallt es. Die ganzen Typ-Probleme treten erst zur Laufzeit auf und müssen mühsam kontrolliert und beseitigt oder umgangen werden.

                  Bei List<T> (C#) bzw. List(of T) (VB) nimmt bereits der Compiler die Prüfungen vor. Es ist dem Programmierer unmöglich, ein falsches Element in die Liste einzufügen; er bekommt immer ein Objekt vom richtigen Typ zurück.

                  Es lohnt sich wirklich nicht, darüber zu diskutieren. Es ist nunmal so:
                  ArrayList gehört auf den Schrottplatz. Stattdessen sind typsichere Collections zu verwenden.
                  Jürgen

                  PS. Du hast recht, ich habe niemals sinnvolle Lösungen und Lösungswege vorgetragen:
                  statt ma sinvolle lösungen und lösungswege vorzubringen!
                  Es ist deshalb völlig abwegig, mich in der Liste der Administratoren aufzuführen.

                  Comment


                  • #10
                    das arraylist veraltet ist und nicht sinnvoll ist, ist für mich verständlich und nachvollziehbar...

                    aber ES TUT MIR SOWAS VON SUPI DOLLE LEID, dass mir beim schreiben spontan arraylist eingefallen ist und ich dieses wort niedergeschrieben habe!
                    BITTE VERZEIH MIR!

                    aber dass du dich da gleich selber angegriffen fühlst verwundert mich...
                    und du kannst mir wirklich nicht sagen, dass diese diskussion bezüglich arraylist und list<t> dem originalthread hilfreich ist.. oder hab ich da was überlesen?

                    ob es abwegig ist dich in der liste der administratoren zu führen oder nicht is mir auch egal!
                    nur solltest du dir gedanken machen bezüglich: wegen nichtigkeiten soeinen wirbel zu machen oder nicht?

                    Liebe Grüße!

                    Comment


                    • #11
                      Bitte alle wieder beruhigen. Ich denke Nooas ArrayList war keine Absicht und List(of T) ist auf jeden Fall besser.

                      Und jetzt wieder back to topic bitte!

                      Danke!

                      Comment


                      • #12
                        dann bringen "wir" die sache mal zum abschluss

                        Code:
                        testArray(i) "ADD" : 11000000: =62 ms
                        
                        testArrayListOF( ADD : 11000000: =328 ms
                        
                        testArrayList ADD : 11000000: =1871 ms
                        
                        testArray Get : 11000000: =74 ms
                        
                        testAList Get : 11000000: =150 ms
                        
                        testArrayList Get : 11000000: =377 ms
                        endlich mal was über performance :-)

                        persönlich komme ich schon bei DIM setzen ja oder nein ins grübeln :-) (in ner schleife)
                        Vor 4,5 Millionen Jahren lernten ~wir~ aufrecht zu gehen!
                        Um heute vorm PC zu sitzen!

                        Comment


                        • #13
                          Ohne deinen Testcode sind die Ergebnisse aber nicht sonderlich aussagekräftig.

                          Comment


                          • #14
                            fasse ich dankend als lob auf
                            Vor 4,5 Millionen Jahren lernten ~wir~ aufrecht zu gehen!
                            Um heute vorm PC zu sitzen!

                            Comment


                            • #15
                              fasse ich dankend als lob auf
                              oh .. äh ... ich bin dir unendlich dankbar. Wärst du so freundlich deinen dazugehörenden Testcode zu zeigen damit ich deine Ergebnisse richtige einordnen kann? Danke Schön

                              Comment

                              Working...
                              X