Java’da Performans Arttırıcı Yollar - Bölüm 4

9 Ocak 2006 tarihli, Java, Programlama köşesine ait yazı.

JavaJava’daki kütüphaneler hakkındaki bu yazı “Thirty Ways to Improve the Performance of Your Java Programs” çevirisinin dördüncü bölümü. Yazıda ArrayList ve LinkedList kullanımı hakkında çok önemli bilgiler var.

6. Libraries (Kütüphaneler)

Bu bölümde java’nın standart kütüphanelerinin nesne ve metodları hakkında birkaç performans sorununu ele alacağız.

6.1 System.arraycopy()

Bir array’deki verileri diğerine kopyalarken System.arraycopy() metodunu kullanmak çok verimli bir yoldur. Örnek olarak N uzunluğunda array’lerimiz olan vec1′den vec2′ye değerleri kopyalamak istiyoruz:

/* array’leri yaratıyoruz */
final int N = 1000000;
int vec1[] = new int[N];
for(int i=0;i
vec1[i] = i;
int vec2[] = new int[N];/* loop içinde kopyalama */
for(int i=0;i
vec2[i] = vec1[i];

/* System.arraycopy() ile kopyalama */
System.arraycopy(vec1, 0, vec2, 0, N);

/* Object.clone() kullanarak kopyalama */
vec2 = (int[])vec1.clone();

Üç değişik metodla kopyalamayı tamamladıktan sonra karşımıza şöyle bir grafik çıkıyor:

loop - 381
System.arraycopy - 40
Object.clone - 150

Görüldüğü üzere System.arraycopy() metodu diğer tekniklere göre, hatta clone() metoduyla neredeyse aynı işlemi yapmasına rağmen hayli hızlı. Unutmamak gerekir ki hangi yolu kullanırsanız kullanın eğer array’de sakladığınız obje referanslarıysa bu referanslar kopyalanır, objelerin kendiler değil.

6.2 Vector mü, ArrayList mi?

java.util.Vector obje referanslarının tutulduğu, dinamik genişleme sağlayan, ve elemanlara random erişimi destekleyen bir class’tır. Vector‘e alternatif olarak java’da bir de ArrayList vardır. Benzer işleri yapan iki class’ın performans karşılaştırması aşağıda veriliyor:

  • Vector‘ün metodları synchronized tanımlanmıştır, yani thread-safe‘tir, tabii ki bazı performans kayıpları vererek.
  • Collection framework ArrayList‘e alternatif olarak bazı artı ve eksileri olan LinkedList sunar.
  • Vector genişlemek istediğinde iki katına çıkar, ArrayList ise boyut olarak %50 artar. Bu bakımdan ArrayList kullanmayacağı alanları daha az işgal eder.

Vector yerine collection framework kullanmak daha cazip görünmekte. Thread programlama konusunda kafanızda soru işaretleri varsa bu sorun wrapper class’lar yardımıyla çözülebiliyor:

List list = Collections.synchronizedList(new ArrayList());

6.3 Array Kapasitesini Atama

ArrayList gibi collection class’ları daha fazla veri alabilmek için yapılarını gerektiğinde otomatik olarak ayarlarlar. Ancak büyük bir array’le çalışıyorsanız, ve ne kadar büyüklükte olacağını az buçuk tahmin edebiliyorsanız ensureCapacity() metoduyla array uzunluğunu atamanız bazı şeyleri hızlandırabilir. Örnek olarak:

final int N = 1000000;
Object obj = new Object();
ArrayList list = new ArrayList();/* kapasite belirtmeden */
for(int i=1;i< =N; i++)
list.add(obj);

/* ensureCapacity kullanarak */
list = new ArrayList();
list.ensureCapacity(N);
for(int i=1;i< =N; i++)
list.add(obj);

Kapasitesini belirtmediğimiz liste her dolduğunda uzunluğunu %50 arttırdığı için N sayısına ulaşana kadar tekrarlanan bu işlemler performans kaybına sebep olacaktır. Zaten ikinci yöntemin %15 daha hızlı çalıştığını test sonuçları göstermiş. Ancak ensureCapacity() metodunu gereksiz yere kullandığımız zaman birçok bellek alanını işgal edeceğimizi unutmayın.

6.4 ArrayList mi, LinkedList mi?

Java collection framework iki çeşit listeyi bizim kullanımımıza sunar: ArrayList ve LinkedList. İlki konsept olarak bir array’e, ikincisi ise adından da anlaşılacağı gibi linked list’e. ArrayList içerisinde bir Object[] tutarken, LinkedList içerisindeki kayıtları birbirine bağlar. İki class’ın farklı durumlarda farklı performans gösterirler.

İlk olarak iki class’la listenin başına yeni elemanlar eklemeyi deneyeceğiz:

final int N = 25000;
/* ArrayList */
ArrayList al = new ArrayList();
for(int i=1;i< =N; i++)
al.add(0, new Integer(i));/* LinkedList */
LinkedList ll = new LinkedList();
for(int i=1;i< =N; i++)
ll.add(0, new Integer(i));

Bu işlemin sonucu ArrayList ile 6610 birim zamanda tamamlanırken, LinkedList ile 340 birim zamanda tamamlanmış. ArrayList‘in başına eleman eklerken tüm elemanların birer aşağıya kaydırılması gerektiğinden bu işlem çok verimli değildir. LinkedList ise tam bu iş için biçilmiş kaftandır, çünkü elemanlar birbirlerine bağlandıkları için yeni gelen elemanın başa yerleşmesi için listenin ilk elemanına bağlanması yeterlidir.İkinci testimiz listelerden art arda raslantısal elemanları kontrol etmek:

/* Listeleri oluşturuyoruz */
final int N = 25000;
Object o;
ArrayList al = new ArrayList();
for(int i=0;i
al.add(new Integer(i));
LinkedList ll = new LinkedList();
for(int i=0;i
ll.add(new Integer(i));/* ArrayList */
for(int i=0;i
o = al.get(i);

/* LinkedList */
for(int i=0;i
o = ll.get(i);

İşlem ArrayList için 30 birim zamanda tamamlanmışken LinkedList için 42371 (!) birim zamanda tamamlanmış. Tabii ki LinkedList ile her raslantısal eleman için listeyi baştan katetmek yerine ArrayList kullanmak çok akıllıca bir yol.Sonuçta listeye elemanları sondan ekliyorsak ve raslantısal olarak çağırıyorsak ArrayList, eklemeleri başa veya orta kısımda herhangi bir yere yapıyor, aynı zamanda elemanlara ardışık olarak erişiyorsak LinkedList kullanmalıyız.

6.5 Listelerle Programlama

Bir önceki bölümde ArrayList ve LinkedList kullanmanın avantaj ve dezavantajlarından bahsettik. Eğer programınızda listelerle çalışıyorsanız ve ArrayList‘lerle LinkedList‘leri bir arada kullanıyorsanız, veya hangisini kullanacağınıza sonradan karar verecekseniz programınızı:

ArrayList list = new ArrayList();
void f(ArrayList list) {…}

gibi yazmak yerine:

List list = new ArrayList();
void f(List list) {…}

şeklinde yazarsanız size acayip bir esneklik kazandıracaktır. Böylece çalışmanızın bir yerinde karar değiştirirseniz dönüşüm fazla zor olmayacaktır.



Yorumlar - Başa Dön

Bu yazı için henüz yorum yazan olmamış. İlk yorumu siz yazmak ister misiniz?



Yorum Yazın

(gerekli)

(gerekli)


Yorum yapacaklar için bilgi:
Verdiğiniz mail adresi sitede asla görüntülenmeyecektir. Sonraki yorumlarınız için isim, e-posta gibi bilgiler cookie olarak bilgisayarınızda saklanacaktır.



Önizleme: