Eigentlich bringst du wohl eher unfreiwillig in deinem Eingangspost schon ein gutes Argument gegen die optimierte Variante: Dein Beispielcode mit Break - Continue liefert nämlich in den Variablen Found1..3 andere Werte als die übersichtlichere Routine mit FindValue. Typischer Copy-Paste-Error halt.
Ja stimmt, naja dies wäre spätestens beim Testen des Codes dann aufgefallen. Aber ja stimmt. Hab vergessen das Zuändern.
Delphi-Quellcode:
for I := Low(TestArray) to High(TestArray) do
begin
case TestArray[I] of
5: Found1 := 5;
50: Found2 := 50; //5;
9: Found3 := 9; //5;
else Continue;
end;
if (Found1<>-1) and (Found2<>-1) and (Found3<>-1) then
Break;
end;
Wenn man Case verwenden kann (falls man nicht auf einen String testen muss) ist diese Variante natürlich auch gut. Naja bei Strings muss man dann auch
If...then...else..if...then...else continue;
verwenden, was aber klar ist. Werde ich mir mal merken.
Es kommt halt immer darauf an.
Hier sehe ich aber auch einen Standard-Fall (sind die Elemente in Menge A in der Menge B enthalten), wo es sich lohnt die eigene Bibliothek um diesen Fall zu erweitern.
Wichtig im Hinblick auf die Performance ist die richtige Art durch die Arrays zu iterieren:
langsam
Delphi-Quellcode:
for a in ValuesA do
for b in ValuesB do
if Comparer.Equals( a, b ) then
vs. schnell
Delphi-Quellcode:
for idxA := Low( ValuesA ) to High( ValuesA ) do
for idxB := Low( ValuesB ) to High( ValuesB ) do
if Comparer.Equals( ValuesA[idxA], ValuesB[idxB] );
denn im letzteren müssen keine Werte kopiert werden.
Okay, dies stimmt nun auch wieder. In diesem Fall ja. Aber man greift dann sowieso standardmäßig auf den Array eintrag direkt hinzu. Dazu fällt mir was anderes gerade ein.
Wenn ich nen Array von Record durchgehen muss, was wäre dann schneller? Einen Pointer auf den Record vom Array speichern und den Pointer zum lesen benutzen oder eher direkt immer über den Array abfragen?
Delphi-Quellcode:
TestP := @TestArray[I];
if TestP^.I = 5 then
Result := TestP^.S;
VS.
Delphi-Quellcode:
if TestArray[I].I = 5 then
Result := TestArray[I].S;
Ich sag dazu nur:
http://c2.com/cgi/wiki?MakeItWorkMakeItRightMakeItFast
Kurzum: Schon vor 30 Jahren war das Problem da, und damals sagte man: Mach das es tut, dann mach es richtig, dann mach es schnell.
Und ja, natürlich ist es legitim sich heutzutage Gedanken über performance und optimierte Verarbeitung zu machen.
Die Frage ist allerdings, ob es wirklich nötig ist.
Beispiel:
Du lädst diese Daten von einer
DB, um sie dann in Deiner Anwendung zu sortieren und zu bearbeiten.
Ist es nicht vielleicht sinnvoller, das filtern und sortieren ggf. auf der
DB zu machen? Vermutlich.
Kann die
DB das gut? Nein? -> Vielleicht nutzt Du nicht die richtige Art von Datenbank. Kann eine anderen Datenbank das besser? Ja? -> Problem gelöst.
Wenn Du eine spezielle Aufgabe hast ist es es vielleicht die beste Option, diese Aufgabe an Tools zu delegieren, die es a) inzwischen meist für umme gibt und b) für diesen Fall hochspezialisiert sind.
Beispiel Suche: Wer implementiert denn heute noch eine schnelle Suche selber? Hochkomplexe binäre baumstrukturen für Indices, die richtig zu verwalten etc... Heute nimmt man da SolR oder Elasticsearch, pumpt die zu durchsuchenden Daten da rein, ein REST-Call und *
wuppdi* sind die Ergebnisse da. Und ja: Man muss ein zusätzliches Softwaresystem installieren und am laufen halten. Und ja: Das kostet im Zweifel auch Hardware. Aber das Ergebnis ist deutlich besser als das, was man selber erreichen könnte (da arbeiten im Zweifel hunderte Spezialisten an komplexester Optimierung), und man bekommt das vor allem inkl. Doku und einer Community die man um Hilfe bitten kann sozusagen frei Haus geliefert.
Stream Processing? Apache Kafka und Konsorten. Logaggregation und Analyse? FluentD, ElasticSearch, Kibana. Verteiltes Caching? Redis.
Es gibt kaum noch Bereiche, die nicht schon durch existierende Lösungen sehr gut abgedeckt sind und sich meist mit wenig Aufwand integrieren lassen.
Da stimme ich dir auch zu. Es ist logisch, wenn man was komplexes haben will, man lieber Komponenten nihmt, die das können und sich schon viele Leute den Kopf darüber zerbrochen haben.
Ich gehöre zu der Art von Programmierer, die sich halt genau selber über solche Sachen gedanken macht und verstehen will zumindest um groben was besser wäre. Manche Dinge verlangen wiederrum speziales Fachwissen in dem jeweiligen Bereich, womit man besser bedient ist, sich auf Komponenten zuverlassen als selber Hand anzulegen. Es geht mir auch um Fälle, wo es speziel auf die jeweilige Daten vielleicht abgestimmt werden muss. Also ich hab schon öfters nen kleinen Algo geschrieben, auch wenn der recht bescheiden war, der meine Zwecke erfüllt.
Wegen irgendwelche Kleinigkeiten finde ich, muss man keine große Lib verwenden. Und in diesem Fall möchte ich schon wisssen, wie es funktioniert. (Dies trifft halt aber nur kleinen Mengen zu, worum es ja in dieser Diskussion mir ja nicht geht
)
Aber wenn ich eine Lib benutze, weil es ein bekanntes Problem ist und es nicht mit der funktioniert, was dann? (Gehen wir auch mal davon aus, dass dies die einzige ist, die nah dran kommt und überhaupt das man in etwa macht, was man will
) Ich kann mir nicht vorstellen, das ein Kunde dann sagt : "Ist egal, dass es lange Dauert, hauptsache funkt."
Dann wäre es sinnvoll, wenn man sich als Programmierer mit anderen zusammen setzt und schaut wo das Problem an der Lib liegt und wie man es lösen kann. Selber schreiben oder Lib selber erweitern, für diesen Zweck. Wäre es dann nicht auch sinnvoll, zuwissen wie diese funktioniert und warum die Leute der Lib das so gemacht haben? Oder denke ich da wieder viel zu weit?
Naja okay, eigentlich kann ich mir die Frage fast selber beantworten...Zu den Leuten von der Lib gehen und sagen "Hi, ehm ja eure Lib macht nicht das was wir wollen. Macht mal." Hab ich recht?