none
Großes Array verändern RRS feed

  • Frage

  • Hallo,

    ich habe aus eine Datei (MAB-Datei, hat was mit Büchern zu tun) ein ca. 2 Mio Felder großes Array gemacht das ich bearbeiten muss. Die Aufgabe ist es, an bestimmten Stellen eine neue Zeile (MAB-Feld) einzufügen. Bisher mach ich das so, dass ich das Array an der Stelle Aufteile und dann mit der neuen Zeile zusammenfüge.

    In etwa so:

    #$i ist die Position wo die neue Zeil hin soll.

    $MAB_TOP= $NEW_MAB[0..($i-1)]
    $MAB_BOTTOM= $NEW_MAB[$i..$MAB_ALL] # MAB_ALL ist die Größe des Array und wird immer neu berechnet.
    $MAB_INPUT = '035  DIESEN DATENSATZ NICHT EINSPIELEN'
    $NEW_MAB = $MAB_TOP+$MAB_INPUT+$MAB_BOTTOM

    Das klappt auch, da ich aber etwa 20000 Ersetzungen machen muss, zieht sich das seeeehr lange hin. 

    Kennt irgendjemand einen Weg ein Array besser und effizienter zu bearbeiten?

    $MAB.inject ($I,$MAB_INPUT) wäre nicht schlecht :-) gibts leider nicht.

    Torsten



    • Bearbeitet Sulucum Donnerstag, 19. August 2021 09:03
    Donnerstag, 19. August 2021 08:59

Antworten

  • Moin,

    zwei Anmerkungen zur Orga:

    1. Code bitte als Code posten (2. Button von rechts)
    2. groß geschriebene Namen sind in PowerShell zwar syntaktisch zulässig, aber extrem unüblich

    In der Sache:

    PowerShell-Arrays sind so ziemlich das langsamste und unhandlichste Konstrukt, das man in PowerShell verwenden kann. Hier ein alter Beitrag von mir, um einen Überblick zu bekommen: https://it-pro-berlin.de/2017/08/powershell-wie-schnell-sind-arrays/

    Ich würde das auf eine der folgenden Arten lösen:

    1. Eine Hashtable mit Ordnungsparameter als Name (muss ausreichend große "Löcher" beinhalten, also vielleicht mit 00000010000000, 00000020000000, 00000030000000 usw. starten), die einzufügenden Werte an die Hashtable anfügen, aber im Namen für die richtige Ordnung sorgen (00000011000000 wäre zwischen 00000010000000 und 00000020000000), am Ende mit einem Enumerator sortieren und ausgeben.
    2. (wäre vermutlich mein Favorit) das Gleiche mit einer SQL-Engine abwickeln - entweder SQL-Server oder halt SQLite. Das hätte den charmanten Vorteil, dass das Ganze nicht im RAM abläuft, sondern dauerhaft bestehen bleibt. Wenn man im RAM rechnen möchte, kann SQLite auch eine In-Memory-Datenbank erzeugen. Dazu habe ich mal einen Vortrag bei uns auf der User Group gehalten: https://it-pro-berlin.de/2021/03/folien-und-sample-code-zu-meinem-vortrag-bei-der-psug-berlin/

    Evgenij Smirnov

    http://evgenij.smirnov.de

    Donnerstag, 19. August 2021 09:28

Alle Antworten

  • Moin,

    zwei Anmerkungen zur Orga:

    1. Code bitte als Code posten (2. Button von rechts)
    2. groß geschriebene Namen sind in PowerShell zwar syntaktisch zulässig, aber extrem unüblich

    In der Sache:

    PowerShell-Arrays sind so ziemlich das langsamste und unhandlichste Konstrukt, das man in PowerShell verwenden kann. Hier ein alter Beitrag von mir, um einen Überblick zu bekommen: https://it-pro-berlin.de/2017/08/powershell-wie-schnell-sind-arrays/

    Ich würde das auf eine der folgenden Arten lösen:

    1. Eine Hashtable mit Ordnungsparameter als Name (muss ausreichend große "Löcher" beinhalten, also vielleicht mit 00000010000000, 00000020000000, 00000030000000 usw. starten), die einzufügenden Werte an die Hashtable anfügen, aber im Namen für die richtige Ordnung sorgen (00000011000000 wäre zwischen 00000010000000 und 00000020000000), am Ende mit einem Enumerator sortieren und ausgeben.
    2. (wäre vermutlich mein Favorit) das Gleiche mit einer SQL-Engine abwickeln - entweder SQL-Server oder halt SQLite. Das hätte den charmanten Vorteil, dass das Ganze nicht im RAM abläuft, sondern dauerhaft bestehen bleibt. Wenn man im RAM rechnen möchte, kann SQLite auch eine In-Memory-Datenbank erzeugen. Dazu habe ich mal einen Vortrag bei uns auf der User Group gehalten: https://it-pro-berlin.de/2021/03/folien-und-sample-code-zu-meinem-vortrag-bei-der-psug-berlin/

    Evgenij Smirnov

    http://evgenij.smirnov.de

    Donnerstag, 19. August 2021 09:28
  • Du könntest ein Dictionary @{} verwenden und die Zeilen in 100er Schritten durchnummerieren.
    Dann fügst du deine Zeilen ein (101, 501, ...).

    Bei der Ausgabe sortierst du nach Key.

    Donnerstag, 19. August 2021 09:30
  • Hallo,

    Ich würde vorschlagen, Hashtable in Ihrem Powershell-Skript zu verwenden.
    https://devblogs.microsoft.com/scripting/easily-create-a-powershell-hash-table/

    Wenn die Antwort hilfreich war, vergessen Sie bitte nicht, positiv zu bewerten oder als Antwort zu akzeptieren.

    Danke, Prakash
    Donnerstag, 19. August 2021 12:54
  • Moin,

    Nachtrag: was Du natürlich auch machen kannst, ist statt Array eine ArrayList verwenden und die Datensätze dazwischen mit der Methode .Insert(Index,Element) einfügen.

    Wie die Performance wird, musst Du testen, aber in jedem Fall besser als jetzt.


    Evgenij Smirnov

    http://evgenij.smirnov.de

    Donnerstag, 19. August 2021 15:25