StrToFloat ohne try...catch... - wie?


  • Mod

    Hallo

    vermutlich ist beides GENAU gleich
    (try...catch wird in Try... verwendet)

    Der Nachteil der zweiten Variante ist - Fehler muessen weiterhion abgefangen werden (Speicher voll, .....)

    MfG
    Klaus



  • ok habe den thread nicht komplett gelesen nur überflogen. try catch sollte natürlich nicht zur laufzeitkontrolle genutzt werden oder besser, wenn man x durchläufe hat.

    und jetzt zu deiner methode....die ist vielleicht ganz schön aber nur wenn man sie zur verfügung hat. ich selbst nutze noch den builder 4 und da gibt es diese methode net. aber dafür habe ich entsprechende komponenten, die lediglich die eingabe einer floatzahl ermöglichen.

    hier gibt man den inhalt also float an und die precision 2 und fertig. gut wenn die funktion zur verfügung steht ist sie sicherlich super.



  • Also ich kann es nicht nachvollziehen...

    Folgende Testroutine:

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    	Button1->Enabled = false;
    
    	AnsiString asZahl;
    	double dZahl;
    
    	for (int i = 0; i < 1000000; i++)
    	{
    		asZahl = AnsiString(i);
    		asZahl += "x";
    		try
    		{
    			dZahl = StrToFloat(asZahl);
    		}
    		catch (EConvertError &ErrObj)
    		{
    			dZahl = 0;
    		}
    	}
    	Button1->Enabled = true;
    }
    

    Ergibt einen Speicherverbrauch von 2808 KB beim Start. Der Speicherverbrauch bleibt nach dem ersten Durchlauf konstant bei 2828 KB.

    Die gleiche Routine ohne die Zeile (also ohne dass die 1 Mill. Exceptions geworfen wird):

    asZahl += "x";
    

    Ergibt einen Speicherverbrauch von 2808 KB beim Start. Der Speicherverbrauch bleibt nach dem ersten Durchlauf konstant bei 2816 KB.

    Ohne Exceptionbehandlung:

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    	Button1->Enabled = false;
    
    	AnsiString asZahl;
    	double dZahl;
    
    	for (int i = 0; i < 1000000; i++)
    	{
    		asZahl = AnsiString(i);
    		dZahl = StrToFloat(asZahl);
    	}
    	Button1->Enabled = true;
    }
    

    Ergibt einen Speicherverbrauch von 2528 KB beim Start. Der Speicherverbrauch bleibt nach dem ersten Durchlauf konstant bei 2804 KB.

    Die Exe wurde ohne dynamisch RTL, ohne Laufzeitpackages und 'Endgültig' kompiliert.

    Ich kann da keinen unnötigen Speicherverbrauch feststellen?!?

    Zugegebenermaßen ist das Laufzeitverhalten bei TryStrToFloat deutlich besser, als bei try catch. Aber das liegt daran, dass die Funktion in Assembler geschrieben ist (was erfahrungsgemäß nicht immer so bleiben muss).



  • Auf jeden Fall ist try...catch langsamer als die Funktion TryStrToFloat. Das und die Tatsache, dass ich auch der Ansicht bin, dass die Methode sauberer ist als das Abfangen der Exception, nötigt mich fast, zum BCB 6 zu wechseln, habe die 5er Version.

    btw: stimmt es, dass es die 6er personal edition kostenfrei gibt?!? wenn ja, auch in Deutsch?



  • Joe_M. schrieb:

    Zugegebenermaßen ist das Laufzeitverhalten bei TryStrToFloat deutlich besser, als bei try catch. Aber das liegt daran, dass die Funktion in Assembler geschrieben ist (was erfahrungsgemäß nicht immer so bleiben muss).

    Das ist - nach Sichtung der Quellen - nicht ganz richtig. TryStrToFloat() und StrToFloat() verwenden intern dieselbe Funktion, deren
    Rückgabewert vom Typ bool von TryStrToFloat() einfach durchgereicht wird, während StrToFloat() eine Exception generiert. Das Generieren
    der Exception dürfte wohl etwas länger dauern, als einfach nur den Rückgabewert durchzureichen.
    Also ist wohl TryStrToFloat() tatsächlich zu bevorzugen, da im anderen Fall eine Exception unnötigerweise erzeugt wird.
    Man fragt sich allerdings, warum Borland diesen Weg nicht schon früher eingeschlagen hat.

    Gruß,

    Alexander



  • Ingo schrieb:

    stimmt es, dass es die 6er personal edition kostenfrei gibt?!? wenn ja, auch in Deutsch?

    Ja, BCB6 Personal gibt es auch in Deutsch kostenfrei für eine Schutzgebühr von 149,- EUR



  • Alexander Kempf schrieb:

    Das ist - nach Sichtung der Quellen - nicht ganz richtig. TryStrToFloat() und StrToFloat() verwenden intern dieselbe Funktion...

    Ups. schäm Hab ich übersehen. Du hast natürlich recht.



  • Ingo schrieb:

    Auf jeden Fall ist try...catch langsamer als die Funktion TryStrToFloat. Das und die Tatsache, dass ich auch der Ansicht bin, dass die Methode sauberer ist als das Abfangen der Exception, nötigt mich fast, zum BCB 6 zu wechseln, habe die 5er Version.

    btw: stimmt es, dass es die 6er personal edition kostenfrei gibt?!? wenn ja, auch in Deutsch?

    vielleicht sollte man sich nicht anhand einer einzelnen funktion genötigt sehen
    zu wechsweln, sondern anhand der bugliste für die einzelnen versionen. ich glaube auch kaum, das die version für die qualität der software so maßgeblich ist.

    ciao



  • Hallo

    Joe_M.
    Also ich kann es nicht nachvollziehen...

    ... must Du auch nicht... vertrau mir einfach... 😃 😉

    Vielleicht habe ich mich ein wenig ungenau ausgedrückt. Speicherverbrauch bedeutet nicht immer, das dieser angezeigt wird. Wenn, wie gesagt, der Speicher fragmentiert wird, hast Du die gleichen Probleme.

    Ich hatte mal ein Programm, bei dem unter anderem ein Datum ausgelesen werden musste. Zur Kontrolle hatte ich auch so eine besagte try - catch - Funktion. Selbiges Datum sollte dann mit einem anderem Wert verglichen werden. Dann folgten weitere Aktionen... z.B. eine Eintragung in eine StringList. Bei ca. 50000 Zeilen war Windows der Meinung : Nicht genügend Speicher... öhm... wie jetzt... der Taskmanager zeigte nur einen Speicherverbrauch von ca. 200 MB von 1 GB vorhandenen. Nun, ich habe dann die Funktion dahingehend geändert, sodaß wenigsten irgendetwas in dem String stehen muß, der umgewandelt werden soll (es kam nur vor : leerer String oder Datumswert). Danach ging es, weil keine Execptions mehr ausgelöst wurden. Sieht doch ganz nach einem Speicherproblem aus...oder ? 😕

    Bis dann denn,
    🙂
    Nash



  • Hi Nash,

    Nash schrieb:

    ... must Du auch nicht... vertrau mir einfach... 😃 😉

    Ich bin ein ungläubiges Kerlchen... Also ich hab hier gestern ein paar Millionen Exceptions geworfen - und mein Rechner läuft immer noch stabil (nein, der wird nie ausgeschaltet). Liegt vielleicht daran, dass ich außer der Exception zu werfen, nichts anderes gemacht habe... Ich hab im Moment allerdings nicht die Zeit das ausführlich zu testen.
    Das von Dir beschriebene Phänomen deutet allerdings eher auf nicht korrekt freigegebene Objektinstanzen hin. Ist es möglich, dass Du dort einen Fehler gemacht hast? Hattest Du den Code-Guard mal dazugeschaltet?
    Außerdem stört fragmentierter Speicher nur die eigene Anwendung, da beim Kontextwechsel zu einem anderen Programm, der von Deinem Programm fragmentierte Speicher in die Auslagerungsdatei geswaped wird (werden sollte).
    Allerdings mach ich mir auch meist die Mühe, die Daten vor der Verwendung - so weit möglich - auf Konsistenz zu prüfen. Zusätzlich lasse ich in Schleifen immer einen Zähler mitlaufen. Wird eine bestimmte Anzahl von Fehlern erreicht, wird ein entsprechender Hinweis ausgegeben und die Funktion beendet.
    Wenn dynamische Objekte verwendet werden setzte ich um die try catch noch ein try __finally, um auf jeden Fall eine zentrale Stelle zu haben, an der diese Objekte wieder freigeben werden.



  • Welchen Gedanken hatte Borland wohl, frage ich mich gerade, eine zuätzliche Methode TryStrToFloat zu implementieren, wenn es doch vorher mit try...catch gut ging. Irgendetwas muss da noch sein.



  • Ingo schrieb:

    Irgendetwas muss da noch sein.

    Hast Du Dir meinen Beitrag weiter oben zur internen Implementierung der Methoden StrToFloat und TryStrToFloat durchgelesen?

    Gruß,

    Alexander



  • sorry, ist mir durchgegangen, gelesen hatte ich ihn schon vorher. ne Geschwindigkeitsfrage also letztendlich, wenns wirklich keine Speicherauswirkungen hat.



  • Ingo schrieb:

    wenns wirklich keine Speicherauswirkungen hat.

    Auf jeden Fall benötigen die Exception-Objekte Speicher. Dieser sollte aber wieder freigegeben werden...



  • Hallo,

    @ Joe_M. :

    Das von Dir beschriebene Phänomen deutet allerdings eher auf nicht korrekt freigegebene Objektinstanzen hin.

    Wie gesagt, das Problem hatte sich erledigt, als die Exceptions nicht mehr ausgelöst wurden. Andere Objekte o.ä. wurden nicht erzeugt.

    Allerdings mach ich mir auch meist die Mühe, die Daten vor der Verwendung - so weit möglich - auf Konsistenz zu prüfen.

    Schonmal versucht ca. 70000 Datensätze zu prüfen. Ich glaube mein Chef würde mir ins Gesicht springen 😮 , wenn ich ihm sagen würde, daß ich erst in 3 Wochen fertig bin, weil ich erst mal alles durchgehen will. Das Problem war ja auch, einen String in ein Datum umzuwandeln, wenn der String aber leer ist... gibt's 'n Fehler.

    Ich sollte evtl. mal erwähnen, daß ich in keinster Weise was gegen try-catch-Konstrukte habe. Ich verwende selbige auch genug, aber eben wenn's geht nicht in Schleifen. 🙂

    Bis dann denn,
    🙂
    Nash



  • Hi Nash,

    Du sollst die ja nicht 'von Hand' prüfen, sondern bevor Du die Daten verwendest im Programm prüfen, ob da grundsätzlich etwas wahrscheinlich verwertbares drinsteht...
    Wenn es z.B. um Datumsangaben in Strings geht, kann man prüfen, ob die Länge des Strings stimmt, ob die Anzahl der Trennzeichen stimmt usw. Wenn da irgendetwas nicht paßt, macht es eh keinen Sinn, zu versuchen irgendetwas zu damit machen.
    Die Rechner heutzutage haben zwar reichlich Leistung, aber das heißt nicht, dass man alles per 'Brute Force' machen kann / soll.



  • Hallo,

    Du sollst die ja nicht 'von Hand' prüfen, sondern bevor Du die Daten verwendest im Programm prüfen, ob da grundsätzlich etwas wahrscheinlich verwertbares drinsteht...

    Darum ging's ja gerade bei dem Programm. Sorfern ein Datum vorhanden ist, mach was mit... :p

    Wenn es z.B. um Datumsangaben in Strings geht, kann man prüfen, ob die Länge des Strings stimmt, ob die Anzahl der Trennzeichen stimmt usw. Wenn da irgendetwas nicht paßt, macht es eh keinen Sinn, zu versuchen irgendetwas zu damit machen.

    Das habe ich ja dann auch getan... 🙂

    Die Rechner heutzutage haben zwar reichlich Leistung, aber das heißt nicht, dass man alles per 'Brute Force' machen kann / soll.

    Genau 🙂

    Bis dann denn,
    🙂
    Nash


Anmelden zum Antworten