Große Datenmengen performant einlesen.

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von Haudruferzappeltnoch.

    Große Datenmengen performant einlesen.

    Hallo,

    wenn ich mit .ReadXml("target.xml") ein DataSet mit 650.000 Zeilen fülle dann dauert das knapp 2 Minuten, das wären ca. 6000 Zeilen in der Sekunde.
    Kann man das schneller hinkriegen? Oder ist das schon eine ziemlich fiese Datensammlung?

    Das Generieren der Daten hat ähnlich lange gedauert, die Xml mit 280MB war aber deutlich zügiger geschrieben (.WriteXml). 5-10 Sekunden.

    Viele Grüße
    Ich lade Xml-Dateien (> 1GB) mit dem Xml.XmlSerializer ein, dauert in der Regel weniger als 30 Sekunden (je nach Hardware).
    Setzt dann aber eine korrekte zuvor erstellte Klasse für die Xml-Datei voraus.

    VB.NET-Quellcode

    1. Dim XS As New XmlSerializer(GetType(Objects.applist))
    2. Dim Data As New Objects.applist
    3. Using Stream As New IO.FileStream(.XmlFiles.AllGames.FullName, IO.FileMode.Open)
    4. Data = CType(XS.Deserialize(Stream), Objects.applist)
    5. End Using


    Nur mal so als Beispiel.

    Wie sieht denn deine Target.xml aus?
    @Haudruferzappeltnoch Die Gestaltung des Inhalts sieht mir iwie suboptimal aus.
    Was stecken denn da für Klassen dahinter?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @Haudruferzappeltnoch Probier mal, die alle zu Integer zu machen, der Festplatte ist es egal, die Konvertierung fällt dann weg.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Mal eben gebastelt ...

    VB.NET-Quellcode

    1. Imports System.Xml.Serialization
    2. '...
    3. Public NotInheritable Class DataSet1
    4. Private Property FieldTab1 As List(Of Tab)
    5. <XmlElement("Tab1")> Public Property Tabs As List(Of Tab)
    6. Get
    7. With Me
    8. If .FieldTab1 Is Nothing Then .FieldTab1 = New List(Of Tab)
    9. Return .FieldTab1
    10. End With
    11. End Get
    12. Set(value As List(Of Tab))
    13. With Me
    14. .FieldTab1 = If(value Is Nothing, New List(Of Tab), value)
    15. End With
    16. End Set
    17. End Property
    18. Sub New()
    19. End Sub
    20. Public Shared Function ReadXml(File As String) As DataSet1
    21. If String.IsNullOrEmpty(File) OrElse Not New IO.FileInfo(File).Exists Then Return Nothing
    22. Dim XS As New XmlSerializer(GetType(DataSet1))
    23. Dim Data As DataSet1 = Nothing
    24. Using Stream As New IO.FileStream(File, IO.FileMode.Open)
    25. Data = CType(XS.Deserialize(Stream), DataSet1)
    26. End Using
    27. Return Data
    28. End Function
    29. Public Shared Sub WriteXml(File As String, obj As DataSet1)
    30. If String.IsNullOrEmpty(File) Then Exit Sub
    31. If obj Is Nothing Then obj = New DataSet1
    32. Dim XSZ As New XmlSerializer(GetType(DataSet1))
    33. Using Stream As New IO.FileStream(File, IO.FileMode.Create)
    34. XSZ.Serialize(Stream, obj)
    35. End Using
    36. End Sub
    37. End Class
    38. Public NotInheritable Class Tab
    39. <XmlElement("col1")> Public Property col1 As Short = 0
    40. <XmlElement("col2")> Public Property col2 As Short = 0
    41. <XmlElement("col3")> Public Property col3 As Short = 0
    42. <XmlElement("col4")> Public Property col4 As Byte = 0
    43. <XmlElement("col5")> Public Property col5 As Byte = 0
    44. <XmlElement("col6")> Public Property col6 As Byte = 0
    45. Sub New()
    46. End Sub
    47. End Class


    Einmal die Klassen

    Und der Aufruf ... (schreiben)

    VB.NET-Quellcode

    1. Dim XmlFile As New IO.FileInfo(IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "XmlFile.xml"))
    2. Dim SW = Stopwatch.StartNew
    3. Dim Obj = DataSet1.ReadXml(XmlFile.FullName)
    4. SW.Show("ReadXml")


    und lesen

    VB.NET-Quellcode

    1. Dim Obj As New DataSet1
    2. With Obj
    3. For i As Integer = 1 To 650000
    4. .Tabs.Add(New Tab With {.col1 = 1, .col2 = 2, .col3 = 3, .col4 = 4, .col5 = 5, .col6 = 6})
    5. Next
    6. End With
    7. SW.Show("CreateData")
    8. SW.Restart()
    9. DataSet1.WriteXml(XmlFile.FullName, Obj)
    10. SW.Show("WriteXml")


    Lesen dauert bei mir etwa 0,6 Sekunden, schreiben etwas mehr.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „BlueLagoonX“ ()

    Stop. Erstmal das DataBinding abschalten. Das heißt: vor dem Laden erstmal als ersten Schritt DGVs von ihrer DataSource (normalerweise bei tDS-Verwendung die BindingSource) abkoppeln mit DGV.DataSource = Nothing und nach dem Laden wieder ankoppeln. Dann schauen, was das mit der Performance macht.
    Als 2. oder Alternativschritt die BS vom tDS ab- und ankoppeln:

    VB.NET-Quellcode

    1. DeineAnsTdsGekoppelteBindingSource.RaiseListChangedEvents = False
    2. DeineAnsTdsGekoppelteBindingSource.SuspendBinding()
    3. 'hier DeinTds.ReadXML("target.xml")
    4. DeineAnsTdsGekoppelteBindingSource.ResumeBinding()
    5. DeineAnsTdsGekoppelteBindingSource.RaiseListChangedEvents = True
    6. DeineAnsTdsGekoppelteBindingSource.ResetBindings(False)

    Das bitte erstmal testen, bevor was an den Daten "optimiert" wird.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.