Exzessives Exceptions werfen



  • Icematix schrieb:

    Ich bin mit der Lösung eigentlich ziemlich glücklich, finde gerade den Try-Block deutlich schöner als das permanente Return-Value-Checking aber man wollte mir die ganze Zeit einreden dass man allein schon durch das Benutzen des Try-Blocks Performancesenkungen eingeht.

    Ein bisschen langsamer ist es schon, aber ReadProcessMemory wird wahrscheinlich 1000 mal mehr machen.



  • Mir war so, als sei das Exception-Handling von C++ auf die Geschwindigkeit im Normalfall optimiert, d.h. das einfache Durchlaufen eines try-Blockes sollte überhaupt nichts kosten, das Werfen und Fangen einer Exception kann dann aber ziemlich teuer werden.
    Hab aber keine Quelle dafür, da müsste man bei den üblichen Verdächtigen suchen (Stroustrup, Meyers, ...).



  • Das Beispiel ist ganz ok.
    Aber ich sehe nicht haufenweise try-Blöcke.
    Allenthalben ein throw reinzubauen, ist oft doof. Viele packen sich die Bibliotheken mit throw voll, um logisch Fehler abzufangen, wo assert viel passender wäre. Aber bei Dir ist der throw-Grund kein Programmierfehler, sondern ein selten anzutreffender Außenweltfehler.
    Dagegen hat keiner was. Du erzähltest von "eigentlich in jeder Funktion ein try", und das kann eigentlich nicht sein. Man wirft, woimmer es nötig ist, aber fangen tut man nur in der main(), in der ThreadFunc() und gelegentlich woanders, wenn man sinnvoll neuaufsetzen kann, wie bei Dir un dem Prozessneugelade.



  • Bashar schrieb:

    Mir war so, als sei das Exception-Handling von C++ auf die Geschwindigkeit im Normalfall optimiert, d.h. das einfache Durchlaufen eines try-Blockes sollte überhaupt nichts kosten, das Werfen und Fangen einer Exception kann dann aber ziemlich teuer werden.
    Hab aber keine Quelle dafür, da müsste man bei den üblichen Verdächtigen suchen (Stroustrup, Meyers, ...).

    Diesmal bei gcc. Die haben (wenigstens mingw) angeblich neulich umgestellt, daß die Exceptions im Normalfall keine Laufzeit mehr kosten, dafür im Wuffall noch ein Bißchen langsamer sind.



  • bool isEven(int n)
    {
        if(n==-12430)
            throw 0;
    	return n%2==0;
    }
    
    int main()
    {
        clock_t start=clock();
        int result=0;
    	#if 1
    	    try{
    			for(int i=0;i<2000000000;++i)
    			{
    				if( isEven(i) )
    					++result;
    			}
    		}
    		catch(int){
    			std::cerr<<"OMG";
    	    }
    	#else
    		for(int i=0;i<2000000000;++i)
    		{
    			try{
    				if( isEven(i) )
    					++result;
    			}
    			catch(int){
    				std::cerr<<"OMG";
    			}
    		}
    	#endif
    
        clock_t end=clock();
        cout<<(end-start)/double(CLOCKS_PER_SEC)<<'\n';
        cout<<result<<'\n';
        return 1;
    }
    

    6.078 vs. 6.828



  • VS 2008


  • Mod

    messerschneider schrieb:

    6.078 vs. 6.828

    Das entspricht dann genau einem Taktzyklus je Schleifendurchgang, bei 2.67 GHz. Da stellt sich dann schon die Frage, ob das wirklich die allgemeinen Kosten von try sind, oder ob der Unterschied hier nicht einfach am Code im Speziellen liegt. Immerhin ist der Schleifenkörper im Falle des inneren try-catch komplexer.



  • Als Faustregel gilt für mich, dass ein Programm im Idealfall auch ohne Exceptions ablaufen können muss. Desweiteren erlaube ich mir das werfen von Exceptions nur in Ausnahmefällen (schliesslich ist der Name bestimmt nicht zufällig gewählt...), doch dort spare ich damit nicht. Wichtig ist es doch, dass man nicht überall alle Exceptions zu fangen versucht. Tritt irgendwo eine Exception auf, dann kocht diese dann auch ziemlich weit hoch, bis sie behandelt und sichtbar wird...



  • Wie alle Features so kann man auch Exceptions mißbrauchen. Dazu gibt es sogar ein Anti-Pattern: http://en.wikipedia.org/wiki/Expection_handling



  • throw new SuccessException("Data saved successfully");
    

    😃 👍


Anmelden zum Antworten