25.6.09

Okunabilirlik performansa karşı - Log4j

private void newUser(String isim, String soyad) {
      ...

      logger.debug("Ad : " + isim + " soyad: " + soyad );

      ...
}

Java ve Log4j kullananlar için son derece sıradan bir kod parçası. newUser fonksiyonunu pek sık çağırmıyorsanız ya da programınızın performansı önemli değilse kod bloğu hala sıradan :) Aksi durumu düşünücek olursak, kodun her yerinde fazlasıyla logger.debug() satırı mevcutsa ve performans sizin için önemliyse?
Çözüm basit
if(logger.isDebugEnabled()) {
      logger.debug("Ad : " + isim + " soyad: " + soyad );
}

Logların birden fazla faydası vardır. Gerek debug sırasında hayatınızı kolaylaştırırlar gerekse kodun okunabilirliğini arttırırlar (en azından isDebugEnabled() gelene kadar öyleydi). İçinde bir sürü if(logger.isDebugEnabled()) satırı olan bir kod parçasının okunabilir olduğunu söylemek oldukça zor. Log yazdırma işini tek satırda yapıp performansı iyileştirmek adına bir alternatif çözüm mevcut.

Öncelikle sorunu doğru belirlemek adına,

logger.debug("Ad : John soyad: Lock");
logger.debug("Ad : " + isim + " soyad: " + soyad );

Yukarıdaki 2 satır arasında performans farkı vardır. 1. satırda tek string vardır ve onu parametre olarak gönderir, 2. satırda parametre olarak tek string alır fakat tek stringi oluşturmak için 4 stringi birleştirme işlemi yapılmaktadır ki performans sorunu buradan doğmaktadır.

Alternatif çözüm olarak değişken parametreli bir fonksiyon yazmak,

private static void logDebug(Object... param) {
      if (logger.isDebugEnabled()) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < param.length; ++i) {
                  sb.append(param[i]);
            }
            logger.debug(sb.toString());
      }
}

Bundan sonra
logger.debug("Ad : " + isim + " soyad: " + soyad );
yerine
logDebug("Ad : ", isim, " soyad: ", soyad );
fonksiyonunu kullanmak. Tek yapmanız gereken parametreleri "+" operatörü yerine "," ile ayırmak. Koddaki değişikliği minimum düzeyde tutarak performansda iyileştirmeye gidebilirsiniz.

Konu ile ilgili yaptığım testin sonuçları da şu şekilde oluştu.

Kod1 :
logger.debug("d" + i + "e" + i + "b" + i + "u" + i + "g" + i);

Kod2:
if(logger.isDebugEnabled())
{
      logger.debug("d" + i + "e" + i + "b" + i + "u" + i + "g" + i);
}

Kod3:
log(“d”,i,”e”,i,”b”,i,”u”,i,”g”,i);

Kod4:
log("1", i, "2", i, "3");


Log seviyesi ERROR de 10milyon iterasyonda Kod1 Kod2 den ortalama 85 kat daha yavaşken Kod3 Kod2 den 10 kat daha yavaştır. log fonksiyonu aldığı parametre sayısına bağlı olarak hızı değişmektedir. Kod4 Kod2 den 8 kat daha yavaştır.

0 comments: