Viele Strings - Return List(Of String) oder globale List(Of String)?

  • VB.NET

Es gibt 27 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Viele Strings - Return List(Of String) oder globale List(Of String)?

    Hallo,

    ich habe eine Klassenbibliothek in der ich in einer Funktion/Sub jetzt ziemlich viele Strings zusammensuche.

    Einige werden jetzt schreiben, probier es doch aus. Das geht nicht so einfach,
    weil ich ganz schön viel implementieren muss und mir evtl. unnötigen Aufwand sparen möchte.


    Außerhalb der Klassenbibliothek würde ich diese nun gerne nutzen, leider weiss ich jetzt nicht was wohl besser geeignet ist.

    -Soll ich eine globale List(Of String) in der Klassenbibliothek deklarieren, auf die ich von außen Zugreifen kann und die in der Funktion gefüllt wird
    -Oder soll ich einen direkten Return in der Funktion ausführen ?

    Es handelt sich um bis zu Edit: 1.000.000 Strings mit einer Durchschnittslänge von 10 Zeichen und einer Maximallänge von 15 Zeichen.

    Wenn ich in der Funktion ein direktes Return ausführe kann ich wohl ganz schön lange warten oder?

    Wie würdet ihr das lösen?

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Kevin Hombre“ () aus folgendem Grund: Sind doch keine 3.000.000 , maximal 1.000.000

    Da muss ich tatsächlich sagen: Probier es aus, denn String-Arrays / Lists mit einer Länge von 3.000.000 ist nicht so üblich, dass man das bereits n Mal gemacht hat. :S
    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!
    Eine mögliche Alternative wäre auch ein Generator.
    Also ein Dings, was die Strings dies ermittelt nicht in eine Liste schreibt, sondern immer sofort als Event verschickt. Damit könnte man so optimieren, dass nirgends ein so großes Objekt vorgehalten werden muß.
    Aber kommt sehr auf Anwendungszweck und die Verhältnisse an, ob das geht.
    3 Mio Datensätze ist üblicherweise nichts, was irgendein Anwender am Stück benötigt.
    Wenn du die Daten in eine DB (oder DB-ähnliche Struktur) packst, kann sich jede Anwendung den relevanten Teil selektieren, ohne gleich das ganze Paket verarbeiten zu müssen.

    Kannst du etwas über den Verwendungszweck verraten, damit man sich etwas darunter vorstellen kann?
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Hey,

    ich hab grad versucht, Deine Frage nachzustellen. Der Versuch, 3 Mio. Strings in einer List (Of) zu speichern, führt nach ungefähr 1.9 Mio. zu einer OutOfMemoryException. Jedenfalls bei mir. Alle Strings hatten eine Maximallänge von 15 Chars.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Also diese Strings werden wie gesagt zusammengesucht.

    Jeder String welcher bei der Suche gefunden wurde, wird nur einmal benötigt und danach nichtmehr.
    D.h. man könnte ihn nachdem er verwendet wurde sofort danach löschen.

    Ich schrieb ja "bis zu 3.000.000 Strings" , das heißt letztendlich soll das der Benutzer selbst entscheiden können.

    Das mit dem Generator bzw. partiellen Abrufen der Strings hört sich gut an. Was gibts da für Möglichkeiten?

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Kevin Hombre“ ()

    Hi
    Events, ein Delegat oder evtl. sogar besser eine eigene Enumerator-Implementierung könnte man da auch schreiben. Wenn man IEnumerable<String> implementiert und einen eigenen IEnumerator<String> dafür implementiert, müssen nicht alle Daten auf einmal geladen werden, sondern können nach und nach abgearbeitet werden. Außerdem wäre das dann z.B. in einer For-Schleife abfragbar. Per Delegat oder damit auch Event könnte man die Daten zwar flexibel nach außen geben, ist aber im Vorgang auch leicht eingeschränkt. List halte ich für eine schlechte Idee. List<T> ist arraybasiert und bei einer Array-Vergrößerung muss Speicherplatz neu angefordert und der alte Inhalt kopiert werden. Somit ist das bei vorher unbekannter Kapazität relativ schlecht und das Befüllen dauert in den meisten Fällen sehr lange und wird vmtl. zum Flaschenhals.
    Persönlich würde ich den Enumerator vorziehen.

    Gruß
    ~blaze~

    ErfinderDesRades schrieb:

    Eine mögliche Alternative wäre auch ein Generator.
    Also ein Dings, was die Strings dies ermittelt nicht in eine Liste schreibt, sondern immer sofort als Event verschickt. Damit könnte man so optimieren, dass nirgends ein so großes Objekt vorgehalten werden muß.
    Danke für eure Antworten!

    Das Problem ist, wenn ich jetzt immer die gefundenen Strings als
    Event nach "außen" sende(mit außen meine ich aus der Klassenbibliothek raus), muss ich diese ja auch außen(also im Programm) empfangen und verarbeiten.

    Ich hab leider vergessen zu sagen, dass ich aus einem bestimmten Grund nur alle 7 Sekunden einen String verarbeiten kann im Programm.

    Das wiederrum heißt(denke ich mal) ich müsste die Nicks wieder zwischenspeichern. Da wären wir wieder bei Reservierung..

    Kevin Hombre schrieb:

    dass ich aus einem bestimmten Grund nur alle 7 Sekunden einen String verarbeiten kann im Programm.

    ich denke schon die ganze zeit, wozu man wohl 3mio Strings durchprobieren muss, und die einzige mir plausible Erklärung ist, dasses sich um einen Brute-Force-Passwort-Angriff handelt.
    Dazu würde auch diese neue Zusatz-Info passen, dass die Tests mit gehörigem zeitlichen Abstand ausgeführt wern müssen (ansonsten wird man wohl gesperrt) - offensichtlich sind die Passwort-Schützer nicht blöde :P
    bei 3 mio Möglichkeiten sagt die statistik, dass du durchschnittlich nach 1,5mio tests erfolg haben wirst, das läuft auf schlappe 10,5mio Sekunden hinaus - und hier versagen meine mathematischen Fähigkeiten - nur so viel: Es wird ganz schön dauern :P :P :P
    Soviel Stromgeld hab ich leider nicht, aber ganz davon abgesehen -> Nein, es handelt sich nicht um Bruteforce.
    Das wäre viel zu Scriptkiddielike und extrem ineffizient.

    Bruteforce ist schon seit paar Jahren out, man kanns wirklich nur sehr begrenzt noch gebrauchen(meistens dann aber auch mit einer Wordlist) - ist einfach so.

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

    Ich hab bisschen nachgedacht.

    Wenn ich eine While Schleife + eine Variable für Index mache (oder eine rückwärtslaufende For Schleife, ist ja egal)
    und dann jedes mal die benutzten Strings aus der List(Of String) lösche und wenn z.B die List(Of String) weniger als 100 Strings hat
    fordere ich irgendwie von der Klassenbibliothek neue an(lass mir die Returnen oder so), wobei ich dann neu Suchen müsste, sofern ich halt nicht zwischenspeichere, was wieder Zeit kostet.

    Wobei, eigentlich bisschen Schwachsinn. Wenn Das Programm sowieso nur 8 Strings in einer Minute verarbeiten kann.

    In 24 Stunden(1440 Min.) schafft das Programm also 11520 Strings zu verarbeiten
    Lässt man das Programm 7 Tage durchgehend ohne Unterbrechung laufen kommt man
    auf 80640 Nicks, da zieht man vllt. 140 Nicks ab wegen verzögerungen oder so und kommt ungefähr auf 80500.

    Verfügbar wären jedenfalls 7.300.253 Strings momentan, wobei wohl keiner so idiotisch ist diese alle Suchen zu wollen.

    Ich werde eine Begrenzung von 1.000.000 einbauen oder das wie ich bereits geschrieben habe mit dem neuen Anfordern von Nicks machen..

    Dennoch interessant das Problem.

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

    In der Funktion, die die Strings verarbeitet, kannst du der Bibliothek sagen, "will neue". Dann bekommt die Anwendung einen neuen Eintrag (basierend auf einem Index).

    Als Beispiel könnte man das so machen:

    Quellcode

    1. WorkWithStrings
    2. =
    3. Event ElementVerarbeiten(tempIndex, string item)
    4. Sub GetElement(tempIndex) => wird von Anwendung aufgerufen
    5. =
    6. Anwendung
    7. =
    8. Sub Verarbeiten(tempIndex, string item) Handles WorkWithStrings.ElementVerarbeiten ==> ruft WorkWithStrings.GetElement(tempIndex + 1) auf.
    9. =

    So kannst du dir eben zusammenbauen, wie du damit hantieren willst.
    Dann hast du auch kein Problem mit dem zwischenspeichern.

    Das Problem mit dem Suchen: lass dir ein IEnumerable mit Lazy-Loading erzeugen. Dann wird nur das geladen, was wirklich genutzt wird :D
    Also: erstmal einen IEnumerable erzeugen und dann per .ElementAt() das Element raussuchen.

    C-Quellcode

    1. IEnumerable<T> items = Database.Table.Where(condition => condition.Property = irgendwas);

    ErfinderDesRades schrieb:

    ist das akzeptabel, dass dein proggi da 4 Monate ununterbrochen dran arbeiten wird?
    Insbesondere wenn festrgestellt wird, dass im allerletzten Schritt noch ein Fehler im Programm ist? :S
    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!
    Hallo,

    ich hab mir das mit dem Yield jetzt mal angeschaut.


    Im Moment habe ich die Funktion wo die Strings gesammelt werden als Iterator Funktion deklariert und zwar so:

    VB.NET-Quellcode

    1. Public Iterator Function SearchFunction(StringsCount As Integer) As IEnumerable(Of String)



    In der Funktion habe ich ja ein Array mit den gefundenen Strings(welches sich aus den Regexmatches bildet).
    Dieses Array durchlaufe ich momentan mit einer For each Schleife und führe auf jeden String yield aus. Ist das richtig so?

    Dann habe ich noch ein Problem.
    -Wie sieht es mit doppelten Strings aus?

    Ich führe zwar auf das Array .Distinct aus, aber dennoch kann es vorkommen, dass aus mehreren Websites ein String erneut in die Liste gelangt.

    Müsste ich dann irgendwie außerhalb der Funktion machen oder?
    Wobei ich dann wieder bei dem Problem mit List(Of T) bin, weil wie soll ich das sonst prüfen
    ohne zu speichern welche ich bereits habe..

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „Kevin Hombre“ ()