schnellste Möglichkeit gesucht, Daten in ein Array einzulesen

  • Moin zusammen,

    Folgendes Problem:

    Habe eine *.txt/*.ini Datei mit ca 1000000 Einträgen (ca.13MB). Sehen alle ca. so aus : 16-133=333.
    Diese Einträge muss ich immer wieder bearbeiten. Habs bis jetzt mit Iniread gelöst, da der erste Teil (16-133) immer bekannt ist. Naja, war nicht so dolle von der Geschwindigkeit ^^.
    Hab das Ganze erstmal in 10 Dateien gesplitet und es geht etwas besser.

    Die ganze Datei in einen Array mit StringSplit($datei,@CRLF) einlesen dauert noch länger.

    Habe mit so "großen" Datenmengen und AutoIt einfach keine Erfahrung und brauchte mal einen Tip, wie ich das am Besten löse

    THX ALL
    LG
    Balti

  • Thx blubbstar für deine Antwort.

    Der Textfile bleibt immer gleich. Was benötigt wird ist einfach nur der Inhalt. Daraus werden ca. 170 Datensätze, allerdings immer wieder andere, gebraucht. Zu jedem Datensatz wird dann noch ein Label (ID wird auch in den Array geschrieben) und noch div andere Sachen erstellt, so dass der gesamte Array im Mom 11 Spalten hat.

    Es wird also immer wieder ein Array mit 170x11 "Zellen" erstellt. Die Erstellung ist auch nicht das Prob, sondern eher das einlesen aus der Txt Datei.

    Die ganze Sache muss allerdings Offline funktionieren und auch recht unkompliziert sein bei der Installation, da das Endprodukt auch bei anderen funktionieren sollte ^^.

    Tja, hab mich leider noch nie mit SQLite beschäftigt (gelogen ist aber schon zu lange her und nicht Offline) und hab da also keinen Schimmer wie ich eine Offline DB anlegen/erstellen muss/kann.

    Wenns irgendwo ne Beschreibung für Idioten gibt ^^ dann immer her damit, lesen geht noch so grade ;) .

    Ansonsten bin ich für jede Hilfe/Ideen Dankbar

    LG
    Balti

  • Hm, wenn du "nur" 170 Datensätze brauchst, müsste das doch auch mit IniRead ganz schnell gehen. Der vordere Wert ist dir ja bekannt, also musste nicht die komplette File einlesen. Ansonsten ist SQLite nichts besonderes. eine lokale Datenbankdatei die mann mit den normalen SQL Befehlen ansteuern kann (Select, Insert into).

    Beispiel ist z. B. unter dem Befehl zu sehen (Anmerkung: bei _SQLite_Open in dem Bsp. ist kein Parameter angegeben, also keine Datenkbankdatei. D.h. die Datenbank wird nur temporär gespeichert und ist nach dem Programmdurchlauf weg.):

    [autoit]

    _SQLite_Query

    [/autoit]
  • Also mit IniRead brauche ich ca. 3-4 Sek um alle 170 Datensätze zu erstellen. Ich denke mal, dass es ja daran liegt, dass in der *.ini ja, obwohl ich nur 170 Datensätze brauche, ca. 100000 Zeilen drin sind. Die müssen ja alle durchsucht werden, bis der passende Datensatz gefunden wurde.

    Hab mal ein bisschen im SQLite Bereich gestöbert und würde gern mal bestätigt haben, ob ich da alles richtig verstanden habe.

    Als erstes müsste ich doch die Datensätze (1000000 in Worten einemillionen^^) in eine SQL Datenbankdatei importieren und danach dann mit Autoit und den passenden Befehlen auf die Datenbankdatei zugreifen.

    Frage 1: Ist das wirklich erheblich schneller als IniRead
    Frage 2: versteh ich das richtig, das keine zusätzliche Software benötigt wird?

    Hoffe nerve nicht zu stark :S . Wenn beide Fragen mit Ja beantwortet werden bin auch "erstmal" wieder weg.

    LG
    Balti

  • Klar darfst du Fragen, kein Problem :).

    1. Warscheinlich ja, bei einer Mio Einträgen leg ich mich allerdings nicht fest.
    2. Keine zusätzliche Software.

    Und dein Gedanke ist schon richtig. Alles erstmal umwandeln in eine Datenbank und diese dann verwenden. Du kannst auch mal die Ini + Code posten, dann kann ich dir da auch ewas helfen, wenn du magst.

    Grüße

  • Sorry,

    Durch Ostern und Besuch zu nichts gekommen.

    Also, die DB hab ich wie folgt erstellt :

    Spoiler anzeigen
    [autoit]


    #include <SQLite.au3>
    #include <SQLite.dll.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $counter = 0
    Local $hQuery, $aRow, $sMsg
    _SQLite_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    _SQLite_Open(@ScriptDir & "\test.db") ; Öffne :memory: Datenbank
    _SQLite_Exec(-1, "CREATE TABLE test (1,2,3);") ; Erzeugt Tabelle
    For $i = 0 To 1000
    ToolTip($i)
    For $i2 = 0 To 1000
    $ini_read = IniRead(@ScriptDir & "\test\test2\test.ini", "test", $i & "|" & $i2, "_")
    _SQLite_Exec(-1, "INSERT INTO test VALUES ('" & $counter & "','" & $i & "|" & $i2 & "','" & $ini_read & "');") ; Fügt Daten ein
    $counter = $counter + 1
    Next
    Next
    _SQLite_Close()
    _SQLite_Shutdown()

    [/autoit]

    Hoffe ist richtig so.

    Eine Abfrage mach ich grad einfach mal so, nur um zu sehen, wie die Geschwindigkeit ist.

    Spoiler anzeigen
    [autoit]


    #include <SQLite.au3>
    #include <SQLite.dll.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $counter = 0
    Local $hQuery, $aRow, $sMsg

    [/autoit] [autoit][/autoit] [autoit]

    _SQLite_Startup()
    _SQLite_Open(@ScriptDir & "\test.db") ; Öffne :memory: Datenbank
    _SQLite_Query(-1, "SELECT 3 FROM test ORDER BY 1;", $hQuery)
    Do
    _SQLite_FetchData($hQuery, $aRow)
    $sMsg &= $aRow[0] & @CRLF
    $counter = $counter + 1
    ToolTip($counter)
    Until $counter = 170

    [/autoit] [autoit][/autoit] [autoit]

    MsgBox(0, "SQLite " & $counter, "Durch Abfrage ermittelte Daten: " & @CR & @CR & $sMsg)
    _SQLite_Close(@ScriptDir & "\test.db")
    _SQLite_Shutdown()

    [/autoit]

    Frage: Ist das so richtig?

    LG
    Balti

    P.S.: Frohe Ostern an alle !

  • Frage: Ist das so richtig?


    Wenn ich das richtig verstanden habe, wolltest du doch bestimmte Einträge nach einem festgelegtem Anfang finden. Richtig? Wenn ja, solltest du diese Überprüfung vielleicht in SQL auslagern (= In den ausgeführten SQL-Befehl), da dies vermutlich schneller geht, als wenn du mit AutoIt jeden Datensatz vergleichst.

    Magnus

    Magnus

  • peethebee

    Ausprobiert hatte ich´s schon. Dachte man könnte das aus der Schreibweise entnehmen.

    Magnus
    Upps, dachte das hätte ich gemacht. Kannst mir das mal näher erklären was du meinst bzw. ein Beispiel geben? Wie gesagt SQL und Ich kennen uns noch nicht lange.

    LG
    Balti

  • Wie gesagt SQL und Ich kennen uns noch nicht lange.

    Schon verständlich. SQL bietet sehr viele Möglichkeiten.

    Sehen alle ca. so aus : 16-133=333.
    Diese Einträge muss ich immer wieder bearbeiten. Habs bis jetzt mit Iniread gelöst, da der erste Teil (16-133) immer bekannt ist.


    Wenn ich´s richtig verstanden habe willst du die Daten "333" aus dem Datensatz "16-133"="333". Dafür würde ich eine Tabelle mir 3 Spalten anlegen:

    SQL
    CREATE TABLE  `test` (
    `ID1` INT( 2 ) NOT NULL ,
    `ID2` INT( 3 ) NOT NULL ,
    `Value` INT( 3 ) NULL DEFAULT NULL ,
    PRIMARY KEY (  `ID1` ,  `ID2` )
    ) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_unicode_ci;
    • Spalte: Der Teil "16"; INT Länge 2
    • Saplte: Der Teil "133"; INT Länge 3
    • Spalte: Der Teil: 333; INT Länge 3

    (ggf. anpassen)

    Zum Laden des Datensatzes mit ID1 = 16 und ID2 = 133 folgenden Befehl verwenden:

    SQL
    SELECT `Value` FROM `test` WHERE `ID1` LIKE '16' AND `ID2` LIKE '133'


    Als Rückgabe erhälste du dann nur denn Wert 333.

    Viele Grüße
    Magnus

    PS1: Du kannst mit der oben verwendeten Tabelle nur einen Eintrag haben, der bei ID1 16 und bei ID2 133 ist. (d.h. 16 und 134 geht; 17 und 133 geht)
    PS2: Die SQL Befehle hab ich nur in nem MySQL-Server getestet, sollten aber auch unter SQLite laufen.

    Magnus

  • Danke dir Magnus für deine Hilfe !

    Hab da nur ein paar kleine Fragen :D

    1. Der Wert 16-133 ist als String anzusehen und sollte als ganzes eingetragen werden. Klar könnte ich den splitten, würde nur gern wissen, ob es einfach ein Mißverständnis zwischen uns beiden ist oder ob da ein tieferer Sinn hinter steckt.

    2. kennst ne Seite, wo ich was zum Thema SQL lesen kann. Mit nichts was erreichen ist irgendwie frustrierend ^^

    3. wie funktioniert die Abfrage genau bzw. wie bekomme ich den Wert in eine Variable. So gehts ja nicht.

    [autoit]

    $data = _SQLite_Exec(-1,"SELECT 3 FROM test WHERE 2 LIKE 100|100")

    [/autoit]

    4. Fertig

    LG
    Balti

    Einmal editiert, zuletzt von MrB (27. April 2011 um 17:44)

  • 1. Der Wert 16-133 ist als String anzusehen und sollte als ganzes eingetragen werden. Klar könnte ich den splitten, würde nur gern wissen, ob es einfach ein Mißverständnis zwischen uns beiden ist oder ob da ein tieferer Sinn hinter steckt.


    Aus Performance-Gründen sollte man immer einen Index haben. Als Index würde ich kein Textfeld verwenden.

    kennst ne Seite, wo ich was zum Thema SQL lesen kann. Mit nichts was erreichen ist irgendwie frustrierend


    Tut mir leid: Nein.

    wie funktioniert die Abfrage genau bzw. wie bekomme ich den Wert in eine Variable. So gehts ja nicht.


    Alle Werte immer in '' setzten. Beispiel s.o..

    Magnus

    Magnus