středa 1. září 2004

Java: reálný dopad vyhození výjimky na rychlost programu

Kdysi dávno jsem četl nebo možná slyšel názor, že výjimky lépe řečeno jejich vyvolání je systémově náročné a zdržuje. Včera jsem našel v nástrojích jednoho našeho projektu třídu, která sloužila k zjištění aktuálního execution kontextu. Tato třída má statickou metodu, která vyvolá výjimku, zpracuje její stacktrace a vrátí jméno třídy a metody, která tuto metodu volala.

Protože se třída pro určení contextu volá docela často napadlo mě onu poučku si ověřit a změřit rychlost vykonávání programu s vyhazováním výjimky.

Jak jsem měřil

Připravil jsem si objekt Dummy, který má statickou metodu, ve které se vyvolá výjimka. Zároveň tato metoda obsahuje výpočet pí, což slouží pouze k simulaci reálné operace.

 
  public class Dummy {	
      public static void doSomethingFishy(boolean withException){
	   if(withException){ 
		try{
		    throw new Exception();             
		}catch(Exception e){
		    //do nothing
		}
	   }
	   double currPi = 0;
           double i = 1;
           do {
               currPi += 4/i - 4/(i+2);
               i+=4;
           } while (Math.abs(Math.PI - currPi) > 1E-7);	
     }
  }
 

Dále jsem si připravil vlákno, které volá statickou metodu doSomethingFishy a cyklus, který vytvoří specifikovaný počet vláken a spustí je.

 
 .
 .
 .
 boolean exception = Boolean.valueOf(args[0]).booleanValue();
 int threadCount = Integer.parseInt(args[1]);
 for(int foo = 0; foo < threadCount; foo++){
    new Thread(new MyThread(exception)).start();
 }
 .
 .
 .

 class MyThread implements Runnable{
    private boolean exception = true;
	    
    public MyThread(boolean exception){
        this.exception = exception;
    }
       
    public void run() {           
        Dummy.doSomethingFishy(exception);
    }
 }	 	
 

Proměnná exception řídí jestli se bude výjimka vyhazovat a threadCount počet spouštěných vláken.

Výsledky měření

Provedl jsem vždy tři měření na 100 vláknech s výjimkou a bez výjimky. Měřenou hodnotou byla doba běhu testu v sekundách, jako časomíra sloužila funkce operačního systému pro vrácení aktuálního času.

S výjimkou (s) Bez výjimky (s)
15,15 15,12
15,16 15,15
15,17 15,23

Z výsledků vyplívá, že vyhození výjimka má nepatrný či spíše žádný vliv na rychlost vykonávání programu. Vzhledem k tomu, že jsem zkoušel proměnlivý počet vláken a výsledky se lišily minimálně, lze prohlásit, že počet vláken má pouze minoritní vliv.

Důležitý dodatek

Cílem tohoto měření bylo prozkoumat reálný dopad vyhození výjimky na rychlost programu, i když se ukázalo, že vliv na rychlost je zanedbatelný, měly by se výjimky používat k signalizaci výjimečných situací. Mezi výjimečné situace rozhodně nepatří řízení běhu programu a nebo zjištění akt. kontextu s každým http požadavkem.

Testovací prográmek obsahuje kromě binárních a zdrojových souborů i spouštěcí dávku pro Windows. Argumenty tvoří true|false - s nebo bez výjimky a počet vláken např. run.bat true 10.