• Offizieller Beitrag

    Warum eigentlich nicht auch das RecordSet-Objekt (ADO) als Alternative zum Array nutzen?


    DAO bzw. jetzt das bessere ADO findet schon Verwendung, in der Rubrik Datenbanken hatte ich dazu bereits gepostet (kann aber sein, dass die Threads nicht mehr existieren, da gabs mal 'nen Crash).
    Als direkte Array-Alternative würde ich persönlich es aber nicht betrachten. Dazu ist es doch zu sehr auf Datenbanken zugeschnitten. ;)

  • Ich kannte das noch nicht (erst Recht nicht damals als der Thread entstand) und ich finde es sehr interessant.
    Vielleicht kann mir aber einer von euch noch kurz eine Frage hierzu beantworten:
    So wie ich dieses Konstrukt verstehe ist es eine Schnittstelle zu einer Datenbank welche als .Net-und auch als COM-Objekt zur Verfügung gestellt wird.
    Die Frage für mich ist daher: Welche Datenbank läuft dann genau im Hintergrund oder stellt das Objekt selbst eine Art native Datenbank zur Verfügung?


    GerhardSchr

    kann man bei dem hash auch mehrere felder benutzen?


    Da hast du deine Antwort ;)
    Entweder das, umständlich mit Arrays in Listen oder per Datenbank.

    • Offizieller Beitrag

    Die Frage für mich ist daher: Welche Datenbank läuft dann genau im Hintergrund oder stellt das Objekt selbst eine Art native Datenbank zur Verfügung?


    Ich habe das bisher so verstanden, dass ADO eine Schnittstelle für Datenbanken aller Art (egal ob relational oder hierarchisch) darstellt mit Basismethoden/ -Eigenschaften von Datenbanken.
    Somit kann man das ADO-Objekt durchaus als eine LowLevel Datenbank ansehen.
    In der Vergangenheit war ADO bzw. damals DAO aber aufgrund des implementierten Recordsets recht verrufen, da dieses eine Schwachstelle im Sicherheitsbereich darstellte. Aktuell sind m.W. diese Sicherheitslücken aber abgestellt.

    Ich nutze ADO vorrangig um meine SQL-Datenbank z.B. mit AutoIt-Skripten anzuzapfen. :D


    Hier mal noch der MSDN-Link zum ADO-Objekt.

  • sowas kann man/ich super nutzen, wenn ich die Active Directory abfrage und dann plötzlich ein Array habe mit ~15 spalten....(Vorname, Nachname, SID, Grupenzugehörigkeit, Mail, letzte Anmeldung....) wenn ich dann eine spalte hinzufügen will, dann wird das immer unübersichtlicher...und wenn ich dann doch nur die Telefonnummer und den Namen brauche, dann muss man immer wissen welche spalte es war (wenn sie sich verschiebt, da neue Spalten dazukommen)...

  • Es tut mit Leid das ich diesen Thread aus den Untiefen unseres Forums heraufholen muss, aber da es sich um eine so tolle Ansammlung von Beispielen handelt möchte ich hiermit zur Fehlerfreiheit dieser beitragen.
    Leider ist AspirinJunkie in der folgenden Beschreibung der "Liste" ein entscheidender Fehler unterlaufen.

    Bei einer Liste stehen die einzelnen Elemente nicht hintereinander im Speicher sondern alle verteilt.
    Damit die Liste zu einer Einheit wird enthalten die einzelnen Elemente zusätzlich zu ihrem Wert noch eine Information darüber wo sich das nächste Element im Speicher befindet (Pointer).
    Das führt dazu das man ohne viel Aufwand Elemente löschen oder hinzufügen kann da einfach nur ein Wert erstellt oder gelöscht werden muss und ein entsprechender Verweis beim vorherigen Element geändert werden muss.
    Eine Liste ist in diesen Fällen enorm schneller als ein Array.

    Prinzipiell sind Listen aber nicht indiziert wie z.B. Arrays - möchte man auf die Elemente zugreifen müsste man theoretisch immer die Liste vom Anfang durchlaufen.

    Denn was er hier beschreibt ist exakt das Verhalten und die Funktionsweise einer sogenannten LinkedList. Im darauf folgenden Beispiel wird allerdings eine sogenannte ArrayList verwendet, was beispielsweise am Namen "System.Collections.ArrayList" und auch unter dem beigefügten Link erkennbar ist.
    Nun ist es allerdings so, dass eine ArrayList intern nicht wie die beschriebene LinkedList arbeitet. Wie schon der Name vermuten lässt, ist die zu Grunde liegende Datenstruktur keine verkettete Liste sondern ein normales Array. Daher sind die von AspirinJunkie genannten Vorteile größtenteils hinfällig. Die einzigen Vorteile die man bei Verwendung einer ArrayList im Vergleich zu einem normalen Array hat sind:

    • Das Array im Hintergrund wird dynamisch vergrößert falls mehr Platz benötigt wird.
    • Beim Löschen von Elementen aus der Liste werden die Lücken im Array automatisch zusammengeschoben.

    Außerdem hat man im Vergleich zum "normalen" Array fast identische Geschwindigkeiten beim Zugriff auf einzelne Elemente, da eben im Hintergrund ein Array existiert.
    Somit ist die "Die Liste" hier wohl doch nur indirekt eine Alternative zum Array.

    LG
    Christoph :)

  • Ja das war mein Wissenstand des Jahres 2007.
    Es ist tatsächlich keine Linked-List. Danke für diesen Hinweis - werde es anpassen.
    Ein normales Array ist es jedoch ebenfalls nicht und ganz und gar nicht nur eine andere Darbietung des eines normalen Arrays.

    Die einzigen Vorteile die man bei Verwendung einer ArrayList im Vergleich zu einem normalen Array hat sind:


    Das Array im Hintergrund wird dynamisch vergrößert falls mehr Platz benötigt wird.

    Beim Löschen von Elementen aus der Liste werden die Lücken im Array automatisch zusammengeschoben.

    Sowie eine deutliche Performancesteigerung beim Hinzufügen und Entfernen von Elementen.
    Eine ArrayList ändert nicht, wie bei einem normalen Array, bei jedem einzelnen Hinzufügen und Entfernen die Größe des Arrays sondern nur in bestimmten Schritten.
    Meist wird das Array verdoppelt oder mal 1.5 multipliziert falls die aktuelle Größe überschritten würde.
    Aber eben erst wenn wirklich die Grenze überschritten wird. Daher finden deutlich weniger Größenänderungen des Arrays statt und somit muss deutlich weniger in andere Speicherbereiche kopiert werden.
    Es ist also deutlich dynamischer als ein normales Array und beim Hinzufügen von Elementen deutlich performanter.
    Hier mal zum Vergleich:


    Eine reine AutoIt-Implementierung des Prinzips hatte ich übrigens hier mal geschrieben: Dynarray-UDF

  • Hallo @AspirinJunkie,

    ich habe eine Frage zum Dictionary. Genauer zu folgendem Ausschnitt aus deinem zugehörigen Beispiel

    AutoIt
    ;//// Einträge hinzufügen ///////////
    $oDict.add ("Berlin", 3395189)
    $oDict.add ("Hamburg", 1743627)
    ; Alternativ (keine Fehler falls schon existiert und auch Werte damit veränderbar):
    $oDict("München") = 1259677
    $oDict("Köln") = 983347
    $oDict("Dresden") = 529781


    Falls ein Eintrag bereits vorhanden ist, tritt bei $oDict.add ein Fehler auf. Mit der einfachen Zuweisung ($oDict("München") = 1259677) können aber auch neue Einträge erstellt werden und bei bereits vorhandenen Schlüsseln wird einfach der Wert überschrieben.


    Bei meinen Tests scheint die Zuweisung der (manchmal viel) bessere Weg zu sein.

    Spoiler anzeigen


    Bei hundert Tausend Elementen war die Zuweisung extrem schneller bei mir. Bei einer Million war der Unterschied aber nur noch klein und da dachte ich: Aha, das lässt bei größeren Mengen nach. Bei zwei Millionen Elementen, blieb der Geschwindigkeitsvorteil der Zuweisung aber stabil. Also scheint mir die Geschwindigkeit hier kein Nachteil zu sein.

    Spoiler anzeigen


    Hundert Tausend
    $oDict.Add | 0,68 Sekunden
    $oDict.Add, wenn | 1,30 Sekunden
    Direkte Zuweisung | 0,35 Sekunden

    Eine Million
    $oDict.Add | 25,04 Sekunden
    $oDict.Add, wenn | 41,85 Sekunden
    Direkte Zuweisung | 24,69 Sekunden

    Zwei Eine Million
    $oDict,Add | 113,47 Sekunden
    $oDict,Add, wenn | 162,77 Sekunden
    Direkte Zuweisung | 107,95 Sekunden

    Könntest du mir (oder ein anderer) erklären, wann man warum die Methode add einsetzen/bevorzugen sollte?

    Grüße autoiter

  • Könntest du mir (oder ein anderer) erklären, wann man warum die Methode add einsetzen/bevorzugen sollte?

    Es stimmt schon - viel spricht nicht dafür .Add statt .Item (das ist die implizite Funktion des Dictionaries hinter der Zuweisung) zu verwenden.
    .Item ist schneller, .Item sieht übersichtlicher aus .Item wirft keine Fehler -> und das hier wäre der einzige Punkt der unter Umständen zu .Add raten könnte.

    .Item hat eigentlich die primäre Aufgabe den Wert zu einem Key zurückzugeben bzw. zu ändern. Hierbei hat es allerdings eine etwas obskure Eigenschaft. Wenn ein Item nicht existiert erstellt diese Funktion einfach ein neues - und zwar ohne ein Wort zu sagen.
    Das macht man sich zwar zu nutze wenn man hiermit die .Add-Funktion ersetzen möchte aber es kann auch zu unvorgesehenen Effekten führen.
    Wenn ein Programmierer an einer Stelle ein Item hinzufügen will bei dem er davon ausgeht dass es nicht bereits existiert, dieses aber aus irgendwelchen Gründen aber doch tut, dann führt .Item zu keinem Fehler obwohl vorher irgendetwas schief gelaufen sein muss. Der Programmierer bekommt hierbei jedoch nichts davon mit - das alte Item wird einfach still und heimlich überschrieben.
    Um das zu vermeiden müsste er sich zwingen jedes mal vorher ein .Exists davor zu schreiben - sieht blöd aus.
    Wenn er aber konsequent .Add verwendet weiß er jedoch dass dieses Szenario damit nicht auftreten kann weil .Add im Gegensatz zu .Item einen Fehler wirft.
    Es hat auch was mit Lesbarkeit des Codes zu tun. Jemand der den Code mit .Item sieht kann erst einmal nicht sofort erkennen ob damit bereits existierende Items geändert werden sollen oder neue hinzugefügt werden sollen.

    Aber in der Summe sehe ich nicht wirklich viel was dann noch für .Add spricht. Und den Performance-Unterschied kann ich mir erst recht nicht plausibel erklären - denn eigentlich müsste im Hintergrund bei beiden das Selbe ablaufen.