Performance mit Scripting.Dictionary oder ähnlichem

  • Hallo zusammen,

    ich muss auf verschiedenen PCs Dateien Indexieren und gewisse Dinge damit erledigen.
    Manchmal brauche ich nur einige dutzend Dateien, manchmal aber mehrere 100'000!

    Eigentlich wäre für mich das Scripting.Dictionary optimal geeignet, da ich schnell Schlüssel mit jeweils einem Wert hinzufügen muss und im Anschluss prüfen muss, ob ein bestimmter Schlüssel existiert!
    Ich muss also nicht nur schnell hinzufügen können, sondern auch schnell auf Existenz eines Schlüssels prüfen!

    Soweit so gut.
    Ich verwende mal folgenden Code auf meinem (momentan) langsamen Rechner:

    [autoit]

    $oDictionary = ObjCreate("Scripting.Dictionary")
    If @error Or Not IsObj($oDictionary) Then Exit MsgBox(0,"Fehler", "Objekt konnte nicht erstellt werden")

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

    $Timer = TimerInit()
    For $i = 0 To 100000
    $oDictionary.Add($i, "Teststring")
    Next
    $End = TimerDiff($Timer)
    MsgBox(0,"Dauer", Round($End, 2) & "ms")

    [/autoit]

    Damit dauert das hinzufügen (auf meinem Rechner) von 100'000 Datensätzen ca. 600ms
    Wenn ich nun aber 1 Million Datensätze hinzufüge, dauert das nicht 10x so lange, also ca. 6 Sekunden, sondern fast 100x so lange (50-60 Sekunden!)

    Das ist natürlich für mich nicht geeignet.
    Aber was wäre schneller?
    Ich habe es schon mit ArrayList, Hashtable, Queue und Stack versucht. (MSDN Link)
    Leider sind diese alle bei bis zu 600'000 Datensätzen langsamer als das Scripting.Dictionary. Dafür sind sie darüber massiv schneller!

    Was für eine Methode könnte ich verwenden, um bei 1 - 20 Millionen Objekten "am schnellsten" zu sein? (Natürlich immer noch in AutoIt). Wäre eine SQLite Datenbank schneller? (Habe noch nie etwas mit Datenbanken gemacht!)

    Ich sage bewusst bis 20 Millionen Einträge, weil ich die AutoIt internen Arrays nicht benutzen möchte. (Obwohl diese - direkt adressiert - am schnellsten sind.)
    In einigen Fällen habe ich eben wirklich mehr als 16 Millionen Objekte!

    Vielen Dank für Eure Hilfe!
    Veronesi

    2 Mal editiert, zuletzt von veronesi (11. September 2012 um 09:01)

  • Eine SQLite Datenbank wird wohl nicht die Lösung sein. Soweit bin ich nun schon mal!
    Mit diesem Script habe ich getestet. Und die Datenbank ist bei allen Werten für $i (von 1 bis 1'000'000) massiv langsamer.
    Gut, SQLite wurde nicht unbedingt wegen der Geschwindigkeit geschaffen... Eine Datenbank bietet andere Vorteile, die ich hier aber nicht benötige!

    Spoiler anzeigen
    [autoit]

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

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

    $Timer = TimerInit()
    _SQLite_Startup()
    $hDB = _SQLite_Open()
    _SQLite_Exec($hDB, "PRAGMA journal_mode = OFF;") ;No Journal = faster
    _SQLite_Exec($hDB, "PRAGMA synchronous = 0;") ;Don't wait for filesystem = faster
    _SQLite_Exec($hDB, "CREATE TABLE Source (Key, Item);") ; Create Table
    _SQLite_Exec($hDB, "BEGIN;") ;Begin of transactions => Faster!
    For $i = 0 to 100000
    _SQLite_Exec($hDB,"INSERT INTO Source VALUES ('" & $i & "', '" & $i & "');")
    Next
    _SQLite_Exec($hDB, "End;") ;End of transactions => Faster!
    _SQLite_Close($hDB)
    _SQLite_Shutdown()

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

    $End = TimerDiff($Timer)
    MsgBox(0,"",Round($End, 2) & "ms")

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

    $oDictionary = ObjCreate("Scripting.Dictionary")
    If @error Or Not IsObj($oDictionary) Then Exit MsgBox(0,"Fehler", "Objekt konnte nicht erstellt werden")

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

    $Timer = TimerInit()
    For $i = 0 To 100000
    $oDictionary.Add($i, "Teststring")
    Next
    $End = TimerDiff($Timer)
    MsgBox(0,"Dauer", Round($End, 2) & "ms")

    [/autoit]

    Also sind weiterhin Ideen gesucht, um eine eine Liste mit Daten temporär zu speichern. Es muss nichts auf der HDD abgespeichert werden. Nur in Variablen, Arrays, Objekten "zwischengelagert"!
    Die Liste ist wie gesagt, zweidimensional. Also Immer Schlüssel und Daten!

    Gruss Veronesi