Efektif Programlama

Efektif programlama tüm yazılım geliştiriciler tarafından önemle dikkat etmesi gereken bir husustur. Günümüz teknolojisiyle küçük ve orta ölçekli sistemlerde çok fark edilmeyebilir. Fakat büyük sistemlerde efektif programlama etkisini fazlaca göstermektedir.

Örneğin ortalama 150 adet servisiniz olduğunu düşünün ve bu servisleri çalıştıran bir servisimiz var. Tüm servisleri çalıştıran bu serviste sadece bir metot parametre olarak string almakta ve gelen parametreyi log olarak basmaktadır. Bu metodu tüm servisler çağırmaktadır.

public static void printLog(String serviceName) {
     System.out.println("Service Name: " + serviceName);
}

Bu metot çok basit bir işlem yapıyor gibi görünmektedir. Gelen string i log olarak basacaktır. Fakat tüm servisler bu metodu kullandığı zaman heapte gereksiz garbage oluşacaktır. Bunun yerine logun basılmasına karar veren bir mekanizma yazabiliriz. Bir tane boolean tanımlarız ve aşağıdaki gibi kullanabiliriz.

public static void printLog(String serviceName) {
     if (isTrace) {
          System.out.println("Service Name: " + serviceName);
     }
}

Fakat bu yöntemde başarısız olacaktır. Çünkü bu metot çağrıldığında bir string tanımlanacak ve kopyası oluşturularak bu metoda gönderilecek ve bu metot da isTrace=false olursa logu basmayacak ve boşuna garbage oluşmuş olacaktır.

Bunun yerine bu metodu çağırdığımızda isTrace kontrolü yaparsak boşuna garbage oluşturmadan loglarımızı bastırabiliriz.

if (isTrace) {
     printLog("test service name");
}

Bu yöntemle metot çağrılmadan önce logun isTrace kontrolü yapılarak boşa garbage oluşturmanın önüne geçilmiş olur.

İkinci olarak dikkat etmemiz gereken bir başka husus döngülerdir. Tüm programlama dillerinde döngüler kullanılmakta ve bu döngüler de ki yapılan küçük yanlışlar bir çığ gibi büyümektedir.

Örneğin döngülerin içerisinde tanımlanan değişkenler büyük sıkıntılara sebep olmaktadır.

while (i < 1000000) {
     String serviceName = "Test service " + i;
     Test obj1 = new Test();
     obj1.setServiceName(serviceName);
     printLog(obj1);
     printLog(serviceName);
}

Burada döngü içerisinde tanımlanmış olan değişkenler döngü döndüğü sürece bu değişkenleri her defasında tekrar oluşturacak ve hafızayı boşuna işgal edecektir. Bunun yerine değişken tanımlamalarını döngülerin dışarısında yaparak tek bir değişken üzerinden tüm işlemlerimizi rahatlıkla ve efektif olarak yapabiliriz.

String serviceName = null;
Test obj1 = new Test();
while (true) {
    serviceName = "Test service 2";
    obj1.setServiceName(serviceName);
    printLog(obj1);
    printLog(serviceName);
}

Değişken veya objeleri ihtiyacımız olduğu zaman tanımlamak daha doğru olacaktır.

if (isTrace) {
     String serviceName = null;
     Test obj1 = new Test();
     while (true) {
          serviceName = "Test service 2";
          obj1.setServiceName(serviceName);
          printLog(obj1);
          printLog(serviceName);
     }
}

Bir başka konu ise if-else if-else deyimlerinde kontrol sıralarının dikkatsizce yazılmasıdır. Geliştirme yaparken yazdığımız kodların sıralaması da önemlidir. Java VM kontrol koşullarını soldan sağa doğru değerlendirmektedir.

if(A() && B() && C(D()))
1. ilk olara A metodu çağrılır ve true gelirse
2. İkinci olarak B metodu çağrılır ve true gelirse
3. D metodu çağrılır ve C metoduna D metodunun çıktısı verilir.

Eğer metotlardan herhangi birisi false gerilirse diğer kontrolleri yapmadan çıkar. Bu durumda kontrol koşullarını akıllıca koymamız daha mantıklı ve efektif olacaktır. Örneğin aşağıdaki gibi bir durum bize çok pahalıya mal olacaktır.

if(expensiveMethodCall() && cheapMethodCall() && cheapBoolEval)

Bunun yerine önce boolean kontrolü yapılmalı ve koşullar aşağıdaki gibi sıralanmalıdır.

if(cheapBoolEval && cheapMethodCall() && expensiveMethodCall())

Son olarak biraz daha detaylı bir bilgi vererek bitirmek istiyorum. Eğer sayılarda karşılaştırma işlemi yapacaksanız eşitlik yerine büyük veya küçük kontrolü yapmak daha kolaydır. Çünkü eşitlik kontrolünde sayının tüm bitlerini kontrol ederken büyüktür veya küçüktür kontrollerinde tamamını kontrol etmeden işlemi bitirecektir.

if(counter==1000000) >>> if(counter>1000001)

Bu tip detayların belki çok büyük katkısı olmayacaktır. Fakat çok fazla kısıtlı kaynaklarda işimize yarayabilir veya mülakat sorusu olarak karşımıza çıkabilir.

Efektif kodlamalar. 🙂