Performance bei textboxen...

  • VB.NET

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Performance bei textboxen...

    Hallo Leute.
    Ich habe ein Programm, was die Registry ausliest und sie 1. in ein Tree list Element einträgt und 2. alles Pfade in einen String schreibt, der dann in eine Textdatei geschrieben wird.
    Ohne das schreiben in einen String und dann in die Textdatei, braucht das Programm so um die 20 Sekunden. Mit schreiben so 5 Stunden und wenn ich verduche jede Zeile in eine Textbox schreiben zu lassen, dann dauert das über 1 Tag. Wie kann ich es also schaffen alle Pfade untereiander in einen String zu bekommen, den ich dann möglichst schnell in eine Textdatei schreiben kann.
    Also was da Performancetechnisch am besten geht.
    Ich hoffe ihr versteht mein Anliegen.
    Hier mal der Code:

    VB.NET-Quellcode

    1. Imports Microsoft.Win32
    2. Public Class frm_main
    3. Dim counter As New Integer
    4. Dim text As String
    5. Private Sub frm_main_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    6. End Sub
    7. Private Function getnodes(ByVal regkey As RegistryKey) As TreeNode
    8. Dim parts() As String = regkey.Name.Split("")
    9. Dim temp As New TreeNode(parts.Last)
    10. Dim subkey As RegistryKey
    11. Dim fullkey As String
    12. If regkey.SubKeyCount > 0 Then
    13. For Each keyName As String In regkey.GetSubKeyNames
    14. Try
    15. subkey = regkey.OpenSubKey(keyName)
    16. temp.Nodes.Add(getnodes(subkey))
    17. fullkey = regkey.Name + "" + keyName
    18. counter = counter + 1
    19. text = fullkey + vbCrLf + text
    20. ' ProgressBar1.Value += 0.0001 '0.0000371377491107366 2692678
    21. Catch ex As Exception
    22. End Try
    23. Next
    24. End If
    25. Return temp
    26. End Function
    27. Private Sub frm_main_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
    28. regTree.Height = Me.Height - 60
    29. End Sub
    30. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    31. counter = 0
    32. Dim rootnode As TreeNode
    33. rootnode = getnodes(My.Computer.Registry.CurrentUser)
    34. regTree.Nodes.Add(rootnode)
    35. 'MsgBox("Current User fertig")
    36. rootnode = getnodes(My.Computer.Registry.CurrentConfig)
    37. regTree.Nodes.Add(rootnode)
    38. ' MsgBox("Current Config fertig")
    39. rootnode = getnodes(My.Computer.Registry.ClassesRoot)
    40. regTree.Nodes.Add(rootnode)
    41. ' MsgBox("Classes Root fertig")
    42. rootnode = getnodes(My.Computer.Registry.Users)
    43. regTree.Nodes.Add(rootnode)
    44. ' MsgBox("Users fertig")
    45. rootnode = getnodes(My.Computer.Registry.LocalMachine)
    46. regTree.Nodes.Add(rootnode)
    47. Me.TopMost = True
    48. My.Computer.FileSystem.WriteAllText("C:\Users\leon\Documents\ArcaniA - Gothic 4\FileList.txt", text, True)
    49. MsgBox("fertig um " & Format(Now(), "hh:mm"))
    50. Label1.Text = counter
    51. End Sub
    52. End Class

    Ich hoffe ihr könnt mir helfen.
    Lg shutdown :D
    Du liest die gesamte Registry auf einmal aus und wunderst dich, dass das lange braucht? Dieser String muss einige Megabyte groß sein, da kommt die TextBox einfach nicht mehr mit, da kann man nichts machen. Notepad und co. laden immer nur den sichtbaren Teil wirklich in die TextBox, das funktioniert mit der normalen Textbox aber so nicht (weil du dann keinen Scrollbalken hättest).

    Artentus schrieb:

    Du liest die gesamte Registry auf einmal aus und wunderst dich, dass das lange braucht? Dieser String muss einige Megabyte groß sein, da kommt die TextBox einfach nicht mehr mit, da kann man nichts machen. Notepad und co. laden immer nur den sichtbaren Teil wirklich in die TextBox, das funktioniert mit der normalen Textbox aber so nicht (weil du dann keinen Scrollbalken hättest).

    ich lese die registry knoten für knoten aus. Funktioniert mit Restriktion. Die Funktion ruft sich immerwiedere selbst auf.
    Auserdem habe ich Scrollbars. Es liegt ja nicht am auslesen, denn dass dauert ca 20 Sekunden.
    Es liegt an der Notation.
    Zeile für Zeile in einen String und den dann in eine Textbox dauert ca 5 Stunden.
    Meine Frage nun:
    Gibt es bessere Ideen die mir erheblich Perfomance sparen könnten, weil ich leider keine Ahnung habe, was wie viel Performance wegnimmt.
    Je es geht mir auch nicht um eine Textbox.
    In dem Code ist ja auch nichts von einer Textbox.
    Das mit der Textbox habe ich nur geschrieben, dass ihr wisst, dass ich das shcon probiert habe und dass das nich klappt.
    In dem Code lade ich den Text Zeile für Zele in einen Sting (Eine Variable ,keine Textbox)
    Und am Ende schreibe ich diesen In eine Textdatei.
    Das dauert an die 5 Stunden.
    Ich will jetzt nicht wissen warum oder dass es nicht mit einer Textbox klappt, sondern mit was ich es sonst machen könnt.
    Danke trotzdem shconmal für deine Mühe :D
    Also braucht es jetzt 5 Stunden, wenn dus in ne TextBox packst, oder wenn dus in eine Datei schreibst?
    Letzteres kann auch recht leicht Probleme machen, da die Festplatte recht langsam ist. Um solche Operationen zu beschleunigen könntest du z.B. gar nicht erst den String bilden, sondern gleich jede Zeile einzeln mit StreamWriter.WriteLine in die Datei schreiben.
    Es dauert 5 stunden es in eine Text Datei zu schreiben.
    Wobei das schreiben an sich nur so 10 Sekunden dauert und dass schreiben in den String so lange(ca 5 stunden).
    Dauert das direkte schreiben jeder einzelnen Zeile in eine Textdatei wirklich kürzer als in einen String(Variable)?
    Naja, es gibt etwas wichtiges, was man über Strings wissen sollte. String sind "immutable" oder zu Deutsch "unveränderlich". Wenn du also etwas an einen String anhängst, dann wird intern eine neue String-Instanz erstellt, der Inhalt aus der alten dort hineinkopiert und das anzuhängende dort angehängt. Und da die Registry einige Millionen Schlüssel besitzt, wird dementsprechend of auch der String im RAM kopiert, und nach einer gewissen Zeit ist der String an sich auch recht lang, es muss also viel kopiert werden.
    Ich weiß nicht, wie viel Performance das bringen wird, aber es muss auf jeden Fall schneller sein.
    Hmm würde es dann villeicht mit einem Array schneller gehen als mit einem String??
    Aber ich könnte mir vorstellen dass man ja dann jedes einzelne Feld wieder auslesen und in die Textdatei eintragen müsste.
    das kostet auch wieder Performance.
    Also das mit dem String wusste ich noch gar nicht. Danke für die Info. Is grundlegend und wichtig zu wissen denke ich.
    Ich versuche es jetzt mal mit StreamWriter

    Also hier ist der Code und es war in 32 Sekunden Fertig. Es waren insgesamt 207866 Pfade. Super Performance. DANKE
    Hier ist der fertige Code für Andere:

    VB.NET-Quellcode

    1. Imports Microsoft.Win32
    2. Imports System.IO
    3. Public Class frm_main
    4. Dim counter As New Integer
    5. Dim text As String
    6. Dim lesen As String = File.ReadAllText("C:\Users\leon\Documents\visual basic\Log.txt")
    7. Dim whatever As New IO.StreamWriter("C:\Users\leon\Documents\visual basic\Log.txt")
    8. Private Sub frm_main_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    9. End Sub
    10. Private Function getnodes(ByVal regkey As RegistryKey) As TreeNode
    11. Dim parts() As String = regkey.Name.Split("")
    12. Dim temp As New TreeNode(parts.Last)
    13. Dim subkey As RegistryKey
    14. Dim fullkey As String
    15. If regkey.SubKeyCount > 0 Then
    16. For Each keyName As String In regkey.GetSubKeyNames
    17. Try
    18. subkey = regkey.OpenSubKey(keyName)
    19. temp.Nodes.Add(getnodes(subkey))
    20. fullkey = regkey.Name + "" + keyName
    21. counter = counter + 1
    22. ' text = fullkey + vbCrLf + text
    23. whatever.WriteLine(lesen & fullkey)
    24. Catch ex As Exception
    25. End Try
    26. Next
    27. End If
    28. Return temp
    29. End Function
    30. Private Sub frm_main_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
    31. regTree.Height = Me.Height - 60
    32. End Sub
    33. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    34. counter = 0
    35. Dim rootnode As TreeNode
    36. rootnode = getnodes(My.Computer.Registry.CurrentUser)
    37. regTree.Nodes.Add(rootnode)
    38. 'MsgBox("Current User fertig")
    39. rootnode = getnodes(My.Computer.Registry.CurrentConfig)
    40. regTree.Nodes.Add(rootnode)
    41. ' MsgBox("Current Config fertig")
    42. rootnode = getnodes(My.Computer.Registry.ClassesRoot)
    43. regTree.Nodes.Add(rootnode)
    44. ' MsgBox("Classes Root fertig")
    45. rootnode = getnodes(My.Computer.Registry.Users)
    46. regTree.Nodes.Add(rootnode)
    47. ' MsgBox("Users fertig")
    48. rootnode = getnodes(My.Computer.Registry.LocalMachine)
    49. regTree.Nodes.Add(rootnode)
    50. Me.TopMost = True
    51. ' My.Computer.FileSystem.WriteAllText("C:\Users\leon\Documents\visual basic\Log.txt", text, True)
    52. whatever.Close()
    53. MsgBox("fertig um " & Format(Now(), "hh:mm"))
    54. Label1.Text = counter
    55. End Sub
    56. End Class

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

    whatever.WriteLine(lesen & fullkey)

    ... wenn sich in der datei schon inhalt befindet, dann wird so, wie es jetzt ist, dieser existierende inhalt mit jedem registry eintrag erneut reingeschrieben. denke da haste nur nen kleinen denkfehler :)

    shutdown schrieb:

    würde es dann villeicht mit einem Array schneller gehen als mit einem String?
    Dafür gibt es in .NET die StringBuilder-Klasse.
    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!

    shutdown schrieb:

    dass andere die das selbe Problem haben, die richtige Lösung sehen können.
    Was ist, wenn die nicht "leon" heißen?
    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!

    RodFromGermany schrieb:

    shutdown schrieb:

    dass andere die das selbe Problem haben, die richtige Lösung sehen können.
    Was ist, wenn die nicht "leon" heißen?
    Das ist dann meine Copy und Paste Bremse.
    Naja der Sinn ist ja auch nicht C & P, zwar kann man sich es kopieren, aber dann sollte man sich auch reindenken und es verstehen und spätestens bei der Fehlermeldung dass Log.txt nicht gefunden wurde, sollte es klar werden :D

    shutdown schrieb:

    Das ist dann meine Copy und Paste Bremse.
    :thumbsup: :thumbsup: :thumbsup:
    Jetzt musst Du den Thread nur noch als erledigt markieren.
    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!