• Cts. Eyl 18th, 2021

Performans Karşılaştırmalı Kod Örneği

Byİlkay Günel

Eyl 12, 2021

Merhabalar.

Bu yazıda size aynı işi yapan iki kod bloğu arasında performans karşılaştırması yaparak iyileştirme yapmanın önemini inceleyeceğiz.

Şimdi bizden şöyle bir şey istendiğini düşünelim. Verilen bir String içerisinde bir sonraki farklı karaktere kadar tekrar eden karakterler silinecek. “abbcbbb” şeklinde verilen String’i abcb şeklinde sıkıştıracağız.

Ben bu soru için ilk olarak metodu şöyle yazmıştım:

public static String transformWithoutPerformanceImprovement(String input) {
    long startTime = new Date().getTime();
    System.out.println("Start Time:" + startTime);
    String returnString = "";
    int length = input.length();
    for (int i = 0; i < length - 2; i++) {
        if (input.charAt(i) != input.charAt(i + 1)) {
            returnString += input.charAt(i);
        }
    }
    long endTime = new Date().getTime();
    System.out.println("End Time:" + endTime);
    System.out.println("Difference Between Start And End Time:" + (endTime - startTime));
    return returnString + input.charAt(length - 1);
}

Şimdi bu transformWihtoutPerformanceImprovement koduna parametre olarak şunu geçelim:

“abbcbbbcccccddddddddddeeeeefffgggggggggghhhhhhhhhhhhhhhhhhiiiiiiiiiiiaaaaaaakkkkkkkkkkkkllllllllllmmmmmmmmmmmmmmmabbcbbbcccccddddddddddeeeeefffgggggggggghhhhhhhhhhhhhhhhhhiiiiiiiiiiiaaaaaaakkkkkkkkkkkkllllllllllmmmmmmmmmmmmmmmabbcbbbcccccddddddddddeeeeefffgggggggggghhhhhhhhhhhhhhhhhhiiiiiiiiiiiaaaaaaakkkkkkkkkkkkllllllllllmmmmmmmmmmmmmmmabbcbbbcccccddddddddddeeeeefffgggggggggghhhhhhhhhhhhhhhhhhiiiiiiiiiiiaaaaaaakkkkkkkkkkkkllllllllllmmmmmmmmmmmmmmm”

Kodu çalıştırdığımda ise şöyle bir çıktı veriyor:

Start Of Main Method:1631445051421
Start Time:1631445051436
End Time:1631445051452
Difference Between Middle And End Time:16
abcbcdefghiaklmabcbcdefghiaklmabcbcdefghiaklmabcbcdefghiaklm

Kodun çıktısı istenendiği gibi ve 16 milisaniye gibi bir sürede işlemi bitirip çıktıyı veriyor. Çıktı doğru fakat bu kod performans testini geçemedi. Ben de sonrasında neleri değiştirebilirim ve kodun hızı artabilir diye düşünmeye ve araştırmaya başladım. En nihayetinde şu şekle gelen bir kod oluştu:

public static String transformWithPerformanceImprovement(String input) {
    long startTime = new Date().getTime();
    System.out.println("Start Time:" + startTime);
    char[] charArrayOfInput = input.toCharArray();
    char previousChar = 0;
    int index = 0;

    for (char c : charArrayOfInput) {
        if (previousChar != c) {
            charArrayOfInput[index++] = c;
            previousChar = c;
        }
    }

    long endTime = new Date().getTime();
    System.out.println("End Time:" + endTime);
    System.out.println("Difference Between Start And End Time:" + (endTime - startTime));

    return new String(charArrayOfInput).substring(0, index);
}

Şimdi aynı input ile bu metodu çalıştırıyorum ve şöyle bir çıktı veriyor:

Start Of Main Method:1631445105236
Start Time:1631445105252
End Time:1631445105252
Difference Between Start And End Time:0
abcbcdefghiaklmabcbcdefghiaklmabcbcdefghiaklmabcbcdefghiaklm

Metodun başlaması ile bitmesi 1 milisaniye dahi sürmedi gördüğünü gibi. Bu nasıl olabilir? İki metot da aynı çıktıyı vermesine rağmen nasıl 15-16 kat daha hızlı sonuç verebiliyor? 2 madde ile durumu özetliyelim.

  1. Birinci metot üzerinde String’in lenght’ini alıp for döngümüzü o lenght kadar döndürdük. String’in kaynak koduna bakarsanız lenght’i size bir byte array’in uzunluğu üzerinden veriyor. İkinci metotta ise String’in lenght’i ile hiç işimiz yok. Buradan bir kısım performans cepte.
  2. Birinci metottaki for döngüsü sürekli input’un üzerinden charAt metodu ile char alıp karşılaştırma yapıyor. Yani for her dönüşünde iki kez metot çağırımı var. İkinci metotda ise başta bir kez String’in char array’ini alıyoruz ve işimizi o char array üzerinden hallediyoruz. İlaveten karşılaştırma için de bir char kullanılıyor, sürekli array ya da string üzerindeki bir önceki gözde ne var diye bakılmıyor, buradan da bir kısım performans cepte.

Gördüğünüz üzere gereksiz değer edinilmesi ve sürekli metot çağırımı yerine sabit değere alıp onun üzerinden ilerlemek bize performans anlamında ciddi getiri sağlayabilir.

Başka bir yazıda görüşene kadar sağlıcakla kalın.

NOT: Yazının kapak resmi https://miro.medium.com/max/1200/1*XS9T7h4Y22IzeQYodwjbzA.jpeg adresinden alınmıştır.

2016 İstanbul Üniversitesi Bilgisayar Mühendisliği mezunuyum. Güncel olarak Paycore'da SoftPOS projesinde Java Developer olarak çalışmaktayım. Büyük oranda Java teknolojileri ile uğraşıp kendimi geliştirmeye çalışıyorum.

İlkay Günel

2016 İstanbul Üniversitesi Bilgisayar Mühendisliği mezunuyum. Güncel olarak Paycore'da SoftPOS projesinde Java Developer olarak çalışmaktayım. Büyük oranda Java teknolojileri ile uğraşıp kendimi geliştirmeye çalışıyorum.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir