Komponentenmanipulation über Index
-
Ok, das this spare ich mir gerne. Ich weiß ja zur Entwicklungszeit wo ich mich bewege.

Das deine Version übersichtlicher ist gebe ich zu und sie entspricht ja auch deinen dargelegten Prinzipien, aber ist sie zur Laufzeit ressourcensparender? Du castest jede Komponente, ich überprüfe bei jeder den Namen... wie bekommen wir raus, was günstiger ist? Gibts da eine Möglichkeit?
-
dynamic_cast wie auch ClassNameIs sollten ähnliche Laufzeiten haben, so dass sich beide Versionen nicht viel nehmen. Sie müssen ja beide intern überprüfen welche Klasse wirklich hinter dem Object-Zeiger steckt. Wenn du es genau wissen willst mußt du es halt mal überprüfen.
-
Jetzt habe ich das mal getestet.
Die dynamic_cast Variante ist deutlich schneller als ClassNameIs (mehr als Faktor 20).
-
Interessant. Ich werd das morgen auch mal prüfen. Ich stell' mir vor, einfach nen Timer vorher zu starten und hinterher abzulesen. Passt das? Oder geht das so nicht?
Edit: immer diese Schreibfehler

Edit2: Schneller ist aber nicht unbedingt ressourcensparender (- CPU-Belastung, Arbeitsspeicher)?

-
Ich habe den Thread nur überflogen, daher ganz bescheiden die Frage: ist es möglich, daß eine TCheckListBox deine Bedürftnisse besser erfüllt?
-
Guten Morgen,
Danke für den Hinweis audacia. Da ich die Liste der fertigen Komponenten noch nicht so aus dem FF kenne (wie wohl die meisten Anfänger), war der prinzipiell gut. Ich habe mir die Komponente gleich mal angeschaut. Leider erfüllt sie nicht die Anforderungen, die ich für die gewünschte Funktionalität meines Programmes stelle. ( Und meine Bedürfnisse erfüllt die sowieso nicht
)
-
@Geschwindigkeitsmessung:
So, habe jetzt mal mit QueryPerformanceCounter gemessen:Kolumbus' Version: ~35ns/50ns (IsChecked / IsNotChecked)
Braunsteins Version: ~20ns/40nsIch komme da nicht auf Faktor 20. Leider verstehe ich die Messung mit QPC nicht ganz, daher kann ich nicht bewerten wie aussagekräftig die Ergebnisse sind.
Hier mal die beiden "Messaufbauten":
// Kolumbus' Version: void __fastcall TForm4::CheckBoxClick(TObject *Sender) { unsigned short j= static_cast<TCheckBox*>(Sender)->Tag; LARGE_INTEGER Frequenz, AnfangsWert, EndWert; unsigned __int64 Latenz; double ErgebnisWert; QueryPerformanceFrequency(&Frequenz); QueryPerformanceCounter(&AnfangsWert); QueryPerformanceCounter(&EndWert); Latenz= EndWert.QuadPart - AnfangsWert.QuadPart; QueryPerformanceCounter(&AnfangsWert); for(unsigned short k= 0; k < (ComponentCount-1); k++) { if((Components[k]->ClassNameIs("TEdit")) && (static_cast<TEdit*>(Components[k])->Tag==j)) { TEdit *VirtualEdit= static_cast<TEdit*>(Components[k]); if(!VirtualEdit->Enabled) VirtualEdit->Enabled= true; else { VirtualEdit->Enabled= false; VirtualEdit->Text= "0"; } break; } } QueryPerformanceCounter(&EndWert); ErgebnisWert= ((((double)AnfangsWert.QuadPart - (double)EndWert.QuadPart) - (double)Latenz) / (double)Frequenz.QuadPart); ErgebnisWert*= -1000000; Label3->Caption= FloatToStrF(ErgebnisWert, ffFixed, 16, 2) + " ns"; }//Braunsteins Version: void __fastcall TForm4::CheckBoxClick(TObject *Sender) { unsigned short j= static_cast<TCheckBox*>(Sender)->Tag; LARGE_INTEGER Frequenz, AnfangsWert, EndWert; unsigned __int64 Latenz; double ErgebnisWert; QueryPerformanceFrequency(&Frequenz); QueryPerformanceCounter(&AnfangsWert); QueryPerformanceCounter(&EndWert); Latenz= EndWert.QuadPart - AnfangsWert.QuadPart; QueryPerformanceCounter(&AnfangsWert); for(unsigned short k= 0; k < (ComponentCount-1); k++) { TEdit *VirtualEdit= dynamic_cast<TEdit*>(Components[k]); if((VirtualEdit) && (VirtualEdit->Tag==j)) { if(!VirtualEdit->Enabled) VirtualEdit->Enabled= true; else { VirtualEdit->Enabled= false; VirtualEdit->Text= "0"; } break; } } QueryPerformanceCounter(&EndWert); ErgebnisWert= ((((double)AnfangsWert.QuadPart - (double)EndWert.QuadPart) - (double)Latenz) / (double)Frequenz.QuadPart); ErgebnisWert*= -1000000; Label3->Caption= FloatToStrF(ErgebnisWert, ffFixed, 16, 2) + " ns"; }Woher hast Du den Faktor 20 Braunstein?
-
Kolumbus: Du hast ja auch nicht nur den Unterschied zwischen IsClass und dynamic_cast gemessen, sondern im wesentlichen deine Schleife (wo der Aufruf von IsClass bzw. dynamic_cast untergeht).
Du mußt einfach eine Schleife mit mehreren Millionen Operationen ausführen, in der nur IsClass bzw. dynamic_cast ausgeführt wird und dafür dann die Zeit messen.
-
Ich habe einfach folgende Schleifen ausgeführt, und die Ausführungszeit gemessen.
for( int i=0; i<500000; ++i) bool test = Sender->ClassNameIs("TEdit"); for( int i=0; i<500000; ++i) bool test = dynamic_cast<TEdit*>(Sender);Das natürlich innerhalb einer OnClick-Funktion.
-
Th schrieb:
Du hast ja auch nicht nur den Unterschied zwischen IsClass und dynamic_cast gemessen, sondern im wesentlichen deine Schleife (wo der Aufruf von IsClass bzw. dynamic_cast untergeht).
Dankeschön, das ist Alles was ich wissen wollte!
Wie realistisch ist das denn, wenn ich die Zeit für zig-tausend gleiche Funktionsaufrufe messe, ohne den restlichen Kontext zu betrachten? Ich halte das Ergebnis nicht für praxisrelevant. Aber ein schöner Laborwert!

-
Du kannst ja jetzt noch die Schleife über deine Komponenten hinzufügen (aber ohne weitere Aktionen auszuführen).
Oder aber du testest die beiden Varianten mit unterschiedlichen Eingaben (aber ich bin mir sicher, daß der String-Vergleich mittels IsClass immer langsamer sein wird, als dynamic_cast - egal für welche Komponente).
Wobei die Frage eigentlich für deine kleine Schleife eigentlich völlig egal ist.