VB Klasse in C auslagern

  • VB.NET

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

    VB Klasse in C auslagern

    Guten Tag Zusammen,

    habe ein Programm mit V Bprogrammiert, dass alle Ordner in einem Verzeichnis erfasst, ordnet und auswertet etc.
    Zuerst durchläuft eine Methode der Klasse Ordner erfassen durch alle Unterordner und speichert ich div. Ordnereig. in einem Objekt einer Klasse.

    Ein Verzeichnis hat etwa 70-100Tsd. Unteordner und der Durchlauf dauert je nach Verschachtelung um die 6-10Std.

    Das ordnen und auswerten der ArrayList mit den Ordnerobjekten geht innerhalb weniger Sekunde.


    Möchte die Durchlaufzeit verringern und daher die Klasse für das Erfassen aller Ordner in C schreiben.

    Ist das möglich und kann dann die VB Klasse auf die Ergebnisse zugreifen?

    C ist nicht OO d.h. man müsste die Infos in Arrays speichern?

    Wie könnte man die Perf. evtl. sinnvoller verbessern?


    Grüße
    Mit C wirste denke ich keinen größeren Geschwindigkeitsvorteil als 1 Sekunde erreichen...
    Das Suchen selbst wird ja schließlich bei beidem von der WinAPI übernommen...

    Überleg dir eher, ob du das per Threading etwas schneller gestalten könntest...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Danke für die schnellen und informativen Posts.

    Wenns mit C nicht so viel schneller geht, werd ich das auch nicht einsetzen.

    Threading habe ich bisher noch nicht gebraucht.
    Wieso sollte das schneller ausführbar sein und kann jm. einen Link für ein gutes Bsp. posten?

    Das hier habe ich gef.
    vbarchiv.net/faq/faq_vbnet_threads.html

    In dem Bsp. wird das Threading so initialisert

    VB.NET-Quellcode

    1. Dim Thread As New Threading.Thread(AddressOf Zählen)


    Meiner Methode werden Parameter übergeben, kann man die durch Kommata getrennt in Klammern hinter den Methodennamen schreiben?

    Grüße
    Du musst einfach die Dateien parallel suchen...
    z.B. nimmst du die Dateien der obersten Schicht und erstellst für jeden Ordner einen Thread, welcher diesen durchsucht...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    C(++) ist mit Sicherheit deutlich schneller. Ich habe vor kurzem eine ähnliche Dateisystemanalyse von .NET auf C++ verlagert und habe den Algorithmus um mehr als das 10-fache beschleunigt (für theoretische Informatiker ist das natürlich nicht nennenswert, weil konstant ;)). Dafür müsstest du natürlich ganz gut C oder C++ programmieren können - ohne CLR!!
    Mit Threading musst du aufpassen - je nach Konfiguration kann das auch gewaltig nach hinten losgehen.
    Bei 6-10 Stunden Laufzeit halte ich aber deinen Algorithmus für ineffizient und deutlich verbesserbar. Poste bitte den gesamten Code, wenn möglich.
    Das hört sich interessant an mit dem Threading, werde das morgen einmal ausprobieren ....

    Ist das jetzt also doch mit C schneller `? :D
    Untere Methode konnte ich bereits verschnellern durch das auslagern von Anweisungen, Einsatz von Array und keiner Collection...



    Hier ist der Code, der zeitintensiven Methode (der Code wir nicht richtig vom Forum gesetzt):

    VB.NET-Quellcode

    1. Imports ScriptingImports System.IOImports System.CollectionsImports System.Windows.FormsImports System.Diagnostics
    2. Public Class ClassOrdnerErfassen Private ArrOrdner As New ArrayList() Private ProjStatProz As Integer = 0 Private Archiv As Boolean = True Private UnterOrdnerEbene As Integer = 0 Private FS As New FileSystemObject Private Ordner As ClassOrdner Private FSfolder As Folder Private Zaehler As Integer = 0 Private OrdnerAnzahl As Integer = 0
    3. Public Sub InitUnterOrdnerErfassen() ArrOrdner.Clear() End Sub
    4. Public Function ErfasseUnterordner(ByRef sFolderPath As String, ByRef sFolderParent As String, ByRef iLastMod As Integer, ByRef OrdnerEbene As Integer, ByRef ParamProjekteAnzahl As Integer, ByRef ParamGUIBearbeitung As GUIBearbeitung) As ArrayList Dim Subfolder As Folder Dim i As Integer = 0
    5. FSfolder = FS.GetFolder(sFolderPath)
    6. 'Alle Unterordner vom Stammordner durchlaufen. For Each Subfolder In FSfolder.SubFolders Application.DoEvents()
    7. Try 'Ordnerebene ermitteln For i = 1 To Len(Subfolder.Path) If Mid(Subfolder.Path, i, 1) = "\" Then UnterOrdnerEbene = UnterOrdnerEbene + 1 End If Next 'Progressbar aktualisieren If UnterOrdnerEbene - OrdnerEbene = 1 Then Zaehler = Zaehler + 1 ProjStatProz = (100 / ParamProjekteAnzahl * Zaehler)
    8. ParamGUIBearbeitung.LabProjVal.Text = Subfolder.Name ParamGUIBearbeitung.LabProjStat.Text = ProjStatProz.ToString & " %"
    9. ParamGUIBearbeitung.ProgBar.PerformStep()
    10. Archiv = True End If
    11. 'Änderungsdatum verifizieren If Archiv Then Archiv = (DateDiff("d", Now().Date, Subfolder.DateLastModified.Date)) > iLastMod = False End If
    12. 'Ordnerobjekte erzeuegen Ordner = New ClassOrdner With Ordner .PropName = Subfolder.Name .PropPfad = Subfolder.Path .PropBearbeitung = Subfolder.DateLastModified .PropOrdnergroeße = Subfolder.Size .PropElternOrdner = Subfolder.ParentFolder.Name .PropArchiv = Archiv .PropOrdnerEbene = UnterOrdnerEbene - OrdnerEbene End With
    13. OrdnerAnzahl = OrdnerAnzahl + 1 ParamGUIBearbeitung.LabAktOrdnerVal.Text = OrdnerAnzahl.ToString
    14. ArrOrdner.Add(Ordner)
    15. Ordner = Nothing UnterOrdnerEbene = 0
    16. ' Rekurs. Aufruf der Methode ErfasseUnterordner(Subfolder.Path, "", iLastMod, OrdnerEbene, ParamProjekteAnzahl, ParamGUIBearbeitung)
    17. Catch ex As Exception
    18. Debug.Print(ex.Message) End Try
    19. Next Subfolder
    20. ErfasseUnterordner = ArrOrdner
    21. End FunctionEnd Class


    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ubunet“ ()

    natürlich ist C schneller, da es vollständig kompiliert wird...
    mach es in einer kompilierten sprache wie:
    C/C++/OBJC
    Pascal/Delphi
    Realbasic
    brainfuck
    ...

    einfacher ists eine liste der sprachen zu machen die für sowas nicht zu empfehlen sind:
    Java, Batch, Php, C#, VB, J#, F#, sowie alle script sprachen

    wenn du es kompliziert mags nimm c, wenn du es fast unlösbar magst nimm brainfuck, aber ich denke am einfachsten wäre für dich Delphi/pascal, Openstep mit Objc, oder realbasic
    Grob solltest du folgende Dinge schon mal ändern:
    • Application.DoEvents verzögert die Ausführung des Programms. Entferne es und verwende einen eigenen Thread (zu unterscheiden von *mehreren* Threads für diese Aufgabe).
    • Deine For-Schleife "Ordnerebene ermitteln" ist denkbar ineffizient: Sie erzeugt mittels "Mid" (was übrigens total veraltet ist) jedes Mal einen neuen String im Speicher. Verwende IndexOf() oder finde eine noch bessere Methode, die das nicht tut.
    • Aktualisiere die GUI nicht so innerhalb des Algorithmus, dass sie diesen stoppt (lass das einen BackgroundWorker oder so tun).

    Wenn du das konsequent umsetzt, dürfte die Methode bereits eine deutlich verkürzte Laufzeit haben.

    Ein Designaspekt noch: Du solltest deine Paramteranzahl reduzieren. So viele brauchst du bestimmt nicht.
    Renati zustimm.

    Weiters habich starke Zweifel, ob eine andere Sprache da performance bringen könnte. Dateizugriffe können nicht schneller als die Festplatte sein, da hilft auch kein Assembler.
    Es ist sogar nicht unwahrscheinlich, dass C++ oder sonstwer intern dieselbe Window-API verwendet wie VB. Allerdings vermute ich bei Stunden-Dauer, dass du einen ungünstigen Algo verwendest, vmt. mit laufender Aktualisierung des Guis.

    Auch Threading machts nicht eigentlich schneller, aber dadurch blockiert wenigstens dein Gui nicht während der Laufzeit.
    Ausser du hast einen sehr listigen Algo, der mehrere kernels ausnutzt - dann vielleicht (ich zweifel immer noch, denn auch 8 Kerne lassen die Festplatte nicht schneller kreiseln ;) )
    natürlich ist C schneller, da es vollständig kompiliert wird...

    Das ist heutzutage beinahe kein Argument mehr...

    Bei der richtigen Programmierung handelt sich dieser Unterschied im Normalfall um wenige ms pro Aufruf...
    Natürlich unsafe Programmieren geht auch nicht, etwas auf die Graka auszulagern wohl auch kaum, aber so schnell wird das wohl auch nicht benötigt...

    Pascal und Delphi sind dann doch wiederum schon sehr veraltet, ich frage mich, ob es da nicht sogar langsamer wird, da die Umsetzung in Maschinensprache rein Theoretisch immernoch besser sein könnte...
    So gesehen ist es wohl am besten direkt in Assembler(oder von mir aus Brainfuck) zu programmieren, aber man wird auch nur dann einen Geschwindigkeitsvorteil erlangen, wenn man es kann...
    Um die WinAPI wird man aber wohl nicht drum herumkommen, es sei denn man bekommt das Programm in den Ring 1(Als Treiber z.B.)..

    Heißt so viel wie: Die Geschwindigkeit lässt sich nur auf die Verwaltung und den Umgang der Variablen verbessern, wobei sich dies bei richtiger Programmierung auch nur sehr schwach auswirken dürfte...Der Dateizugriff bleibt gleich schnell...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Ist das jetzt also doch mit C schneller `

    natürlich C/C++ viel schneller als NET.


    Ist das möglich und kann dann die VB Klasse auf die Ergebnisse zugreifen?

    ...das ist der gröste misst was du machen kannst...mein tipp, schreib dein projekt weiter in C/C++.

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