Zwei ForSchleifen performanter/übersichtlicher machen ?

  • Allgemein

Es gibt 24 Antworten in diesem Thema. Der letzte Beitrag () ist von ~blaze~.

    Zwei ForSchleifen performanter/übersichtlicher machen ?

    Guten Morgen,
    in meinem Projekt durchlaufe ich sehr oft ein zwei dimensionales Array.
    Da dies sehr oft vorkommt wollte ich mal in der Welt der LINQ und Lambada-Ausdrücke nachschauen ob sich da etwas finden lässt. Das ganze sollte die Übersichtlichkeit (Codehöhe) verringern.
    (Eventuell auch Performance)
    Anzumerken wäre noch dass ich innerhalb der beiden Schleifen einige Abfragen tätige. Zusätzlich bräuchte ich den Index des Elements in der Auflistung.
    Hier mal ein Beispielcode.

    VB.NET-Quellcode

    1. For row As Integer = startRow To endRow - 1
    2. For length As Integer = startLength To endLength - 1
    3. If row = startRow OrElse length = startLength Then
    4. isNew = True
    5. End If
    6. If isNew = True Then
    7. If array(row, length).Value = 0 Then
    8. list.Add(New Stop(New Point(length, row)))
    9. isNew = False
    10. End If
    11. End If
    12. Next
    13. Next
    (Eine der unkompliziertesten Varianten)

    Kennt da jemand eine schöne Abkürzung für ?
    Selbst konnte ich nichts Brauchbares finden.
    (Immer nur sowas stackoverflow.com/questions/73…sional-array-using-linq-c)
    Warum so umständlich? Ist es nicht das Gleiche wie:

    VB.NET-Quellcode

    1. For row As Integer = startRow To endRow - 1
    2. For length As Integer = startLength To endLength - 1
    3. If (row = startRow OrElse length = startLength) AndAlso array(row, length).Value = 0 Then
    4. list.Add(New Stop(New Point(length, row)))
    5. End If
    6. Next
    7. Next


    ?

    Du brauchst doch IsNew überhaupt nicht, weil du sie im gleichen Schleifendurchlauf verarbeitest und später nicht mehr brauchst.

    EDIT: bzw. wozu brauchst du die Schleife überhaupt, wenn sonst nichts passiert?

    LaMiy schrieb:

    eine schöne Abkürzung
    wäre dies:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    2. For row As Integer = startRow To endRow - 1
    3. For length As Integer = startLength To endLength - 1
    4. If Array(row, length).Value = 0 Then
    5. list.Add(New Stop(New Point(length, row)))
    6. Exit Sub
    7. End If
    8. Next
    9. Next
    10. End Sub
    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!

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

    LaMiy schrieb:

    Das ganze sollte die Übersichtlichkeit (Codehöhe) verringern.
    Ich gehe mal davon aus, du willst durch Verringerung der "Codehöhe" die Übersichtlichkeit erhöhen.
    Zunächst würde ich da die umständliche Logik verkürzen.

    VB.NET-Quellcode

    1. For row As Integer = startRow To endRow - 1
    2. For length As Integer = startLength To endLength - 1
    3. If row = startRow OrElse length = startLength Then AndAlso array(row, length).Value = 0 Then list.Add(New Stop(New Point(length, row)))
    4. Next
    5. Next


    Edit:
    Wenn du jetzt diesen Beitrag mit dem darüberliegenden Vorschlag verknüpfst, dann gibt das nicht nur kurzen, sondern auch noch performanten Code.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    @petaod
    Dein Code hat einen Fehler, wenn er weg ist, dann entspricht er meinem Code. :P
    Der darüberliegende Beitrag enthält die IsNew-Variable, sie wurde nur für den ersten Durchlauf verwendet, also überflüssig. ;)

    @RodFromGermany
    Der ursprüngliche Code prüft nur die ersten beiden Indizien, danach wird die IsNew auf False gesetzt. ;)

    Deswegen frage ich mich, wozu die Schleife überhaupt da ist, denn außer beim ersten Durchlauf, passiert da nichts.

    petaod schrieb:

    Zunächst würde ich da die umständliche Logik verkürzen.
    Das ist es leider nicht, denn Du testest nur die beiden Start-Indizes.
    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!
    Jo. Ihr habt recht. Der Code dürfte wahrscheinlich nicht mal richtig kompilieren.
    Soll ich jetzt sagen, dass es eine C&P-Bremse ist? :D

    Vielleicht sollte man einfach manchmal vorher nochmals durchlesen und nachdenken, bevor man auf "Absenden" klickt.
    Das nächste Mal dann...

    Ich korrigiere jetzt dennoch nichts, denn eigentlich wurde schon alles gesagt.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    affrop schrieb:

    wo holst du denn die werte für row und length her?
    Bei der ganzen Sache handelt es sich um darum, dass ich Text auf einer Bitmap finden möchte.
    Dazu gehe ich zuerst jede Reihe durch und prüfe ob "da was ist".
    Anschließend. Gehe ich in dem gefundenen Bereich von rechts nach links um den Start des Textes zu finden.
    Das ganze passiert noch ein paar mal um auch die Buchstaben genau eingrenzen zu können.
    Für 'all diese Schritte muss ich zwei Schleifen benutzen. Da es der Hauptteil des ganzen ist ,muss dieser zu performant wie möglich sein.
    @RodFromGermany:'s Lösung klappt. Wieso ist mir noch nicht ganz klar.

    @sonne75: Den Codeauschnitt habe ich gekürzt, da ich den Vorgang von der eigentlichen Programmlogik (Text erkennen) trennen wollte.

    Danke schon mal an alle wegen der Logik mit newLine. Da hatte ich irgendwie ein Brett vor'm Kopf :)

    sonne75 schrieb:

    Der ursprüngliche Code prüft nur die ersten beiden Indizien, danach wird die IsNew auf False gesetzt. ;)
    Nein. :thumbsup:
    -----
    @LaMiy:: Ich hab Dein Flag durch das Exit Sub ersetzt und Deine Tests so belassen.
    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: Ja danke dafür ! :thumbup:
    Und auch an alle anderen die geholfen haben.
    Mein Code ist jetzt schon mal auf jeden Fall übersichtlicher.

    Aber wollen wir doch mal etwas größenwahnsinnig werden ( :thumbsup: ) und doch probieren es mit LINQ oder Lambada zu schaffen. (Soweit das möglich/besser/kürzer ist)
    Ich hatte da an sowas in der Art gedacht: list.ForEach(sub(x) x.Name = "New Name") Ist aber noch Neuland für mich, deshalb weiß ich nicht wie ich es anpacken soll.
    (Es ist jetzt auch nicht mehr so dass ich eine Lambada oder LINQ Variante unbedingt benutzen will, sondern dass ich es eher verstehen möchte)

    Hat jemand eine Idee ?
    Nach meiner Erfahrung wird Code übrigens sehr viel übersichtlicher, wenn man die Tabulator-Weite nicht von 4 auf 8 erhöht, sondern im Gegenteil eher verringert. Ich zum Beispiel arbeite grundsätzlich mit einer Tabulator-Weite von 2. Dann werden auch Code-Segmente, die bis zu 10 Mal eingerückt sind - aus welchem Grund auch immer - deutlich besser lesbar als wenn man das auf 8 hat so wie du ;).

    LaMiy schrieb:

    Lambada

    Yeah... dance :love:
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    Kommt drauf an. Wenn die Schleife gut parallelisierbar ist, dann wirst du damit schon einiges erreichen können, wenn sich die einzelnen Threads jedoch gegenseitig zu stark ausbremsen, z.B. durch aufeinander warten, dann kanns sogar langsamer sein.

    LaMiy schrieb:

    Paralell.For
    sieht bei diesen Schleifen nicht sonderlich gut aus, da Du das 1. Element suchst, das eine Bedingung erfüllt, um dann rauszugehen.
    Der Parallel.For.Algo könnte da ggf. das 2. Item finden und rausgehen, da wäre das Resultat falsch.
    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!