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



  • Hallo Nash,

    gebe dir vollkommen Recht! TryStrToFloat kannte ich bisher auch nicht, gefällt mir aber.
    Es geht auch nicht unbedingt um den Speicher, sondern darum wie sauber programmiert ist! Und die Lösung mit try catch ist irgendwie nicht so ganz sauber und macht den Quellcode meiner Einsicht nach unnötig unübersichtlich.

    Grüße,
    Robert



  • Die Funktionen gibt es erst ab dem 6er...

    Jetzt würde mich nur interessieren, wieso ein try... catch so viel Speicher verbrauchen soll?? Ich setze das sehr intensiv ein, um bestimmte Konditionen abzufangen, aber mir ist bisher nicht aufgefallen, dass das einen enormen Speicherverbrauch verursachen soll. Ehrlich gesagt kann ich das auch nicht nachvollziehen.



  • rowisoft schrieb:

    Hallo Nash,

    gebe dir vollkommen Recht! TryStrToFloat kannte ich bisher auch nicht, gefällt mir aber.
    Es geht auch nicht unbedingt um den Speicher, sondern darum wie sauber programmiert ist! Und die Lösung mit try catch ist irgendwie nicht so ganz sauber und macht den Quellcode meiner Einsicht nach unnötig unübersichtlich.

    Grüße,
    Robert

    das glaubst du doch jetzt nicht im ernst? man sollte auch drauf hinweisen, dass es mehr möglichkeiten als nur try catch gibt. aber das deswegen eine software unnötig speicher verbraucht habe ich noch nie gesehen und der code wird dadruch nicht unübersichtlicher sondern zeigt mir, dass auf das abfangen der fehler geachtet wurde...fertig....



  • Hallo!

    aber das deswegen eine software unnötig speicher verbraucht habe ich noch nie gesehen

    Hab ich nicht auch geschrieben, dass es NICHT um den Speicher geht?

    und der code wird dadruch nicht unübersichtlicher sondern zeigt mir, dass auf das abfangen der fehler geachtet wurde...fertig....

    Das meinst du aber jetzt wohl nicht ernst?
    Es muss nicht bedeuten, dass das ein Fehler ist, wenn man prüfen möchte, ob StrToFloat hinhauen wird.

    Aufgabe: Du hast ne Textdatei mit irgendwelchen Werten in jeder Zeile. Jetzt sollst du rausfinden, ob da wirklich nur Floats in jeder Zeile sind, oder ob da auch ein Text dabei ist - und dann möchte ich wissen, wie oft Text drin ist.
    Mit try catch müsstest du alle x-tausend Zeilen überprüfen - im dümmsten Fall hast du x-tausend Exceptions gehabt, die du alle unterdrückt hast.
    Ausserdem sagt dir die try catch Methode noch lange nicht sicher, dass es sich nicht um einen Float-Wert handelt. Was ist wenn ein anderer Fehler auftaucht - keine Ahnung, Speicher voll.... - dann bringst du die Meldung, dass kein gültiger Float, obwohls gar net stimmt, weil ein anderer Fehler ist.

    Ich will nicht sagen, dass die try catch Methode ein Verbrechen ist. Warum aber sollte ich auf TryStrToFloat verzichten, wenn ich diese schöne Methode doch habe??!? Damit der Code unübersichtlicher wird? (und das wird er mit Sicherheit, wenn ich statt 1 Zeile min. 3 hab)

    Ich denke, da wirst du mit deiner Meinung ziemlich einsam dastehen, wenn deine Meinung ist, dass "TryStrToFloat" nicht sauberer ist als "try catch"

    Ausserdem war die Frage dieses Themas: StrToFloat ohne try...catch... - wie?
    Und wenn du wieder schreibst mit "try...catch..." ist die Aufgabenstellung nicht erfüllt, 0 Punkte, Note 6 oder gekündigt 🙂

    Grüße,
    Robert


  • 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.


Anmelden zum Antworten