C# VE JAVA NESNE YÖNELİMLİ PROGRAMLAMA DİLLERİNDE COLLECTION FRAMEWORK'LERİN KARŞILAŞTIRMALI PERFORMANS ANALİZLERİ Şükran EBREN KARA YÜKSEK LİSANS TEZİ ELEKTRONİK BİLGİSAYAR EĞİTİMİ GAZİ ÜNİVERSİTESİ BİLİŞİM ENSTİTÜSÜ OCAK 2014 ANKARA C# VE JAVA NESNE YÖNELİMLİ PROGRAMLAMA DİLLERİNDE COLLECTION FRAMEWORK'LERİN KARŞILAŞTIRMALI PERFORMANS ANALİZLERİ Şükran EBREN KARA YÜKSEK LİSANS TEZİ ELEKTRONİK BİLGİSAYAR EĞİTİMİ GAZİ ÜNİVERSİTESİ BİLİŞİM ENSTİTÜSÜ OCAK 2014 ANKARA iv C# VE JAVA NESNE YÖNELİMLİ PROGRAMLAMA DİLLERİNDE COLLECTION FRAMEWORK'LERİN KARŞILAŞTIRMALI PERFORMANS ANALİZLERİ (Yüksek Lisans Tezi) Şükran EBREN KARA GAZİ ÜNİVERSİTESİ BİLİŞİM ENSTİTÜSÜ Ocak 2014 ÖZET Bu çalışmada, java Collections Framework'teki ve C#’taki koleksiyonlar karşılaştırılarak, belli başlı performans testlerine tabi tutuldu. Aralarındaki benzerlikler ve farklılıklar ortaya konularak kullanım alanları belirlendi. Bu belirleme, hazırlanan uygulama programları sayesinde gerçekleştirildi. Uygulama programlarında dışarıdan alınan büyük boyutlu veriler arama, sıralama, yerleştirme, silme gibi işlemlere tabi tutularak koleksiyonlar arasındaki performans ve bellek tüketimleri karşılaştırılacak testler yapıldı. Koleksiyonlar için yapılan testlerle elde edilen bilgiler analiz edilerek yorumlandı. Böylece her iki programlama dil yapısı için sağlanan Collections Frameworkler karşılaştırılmış oldu. Bu karşılaştırma sonucunda Java koleksiyonlarının performans açısından C# koleksiyonlarından daha iyi iken kullanılan bellek açısından C# koleksiyonlarının daha az maliyetli olduğu belirlendi. Bilim Kodu Anahtar Kelimeler Sayfa Adedi Tez Yöneticisi : 902.3.006 : Java, C#, koleksiyon, performans, analiz, framework : 105 : Yrd. Doç. Dr. Nursal ARICI v COMPARATIVE PERFORMANS ANALYSIS OF THE COLLECTIONS FRAMEWORK IN C# AND JAVA PROGRAMMING LANGUAGES (M.S. Thesis) Şükran EBREN KARA GAZI UNIVERSITY INFORMATICS INSTITUTE January 2014 ABSTRACT In this study, the collections in Java Collections Framework and C# are compared, and they are subjected to some definite performance tests. Their fields of usage are defined by giving their similarities and differences. This defining has been done thanks to the application programs. Large scale data that is taken outside in application programs are subjected to some processes like searching, ordering, removing and some tests were done to compare the performance between collections and memory consuming. The tests and the data collected from these tests are analyzed. Thus, Collection Frameworks that are provided for programing two languages are compared. As a result of this study it can be said that Java Collections are better than C# collections in terms of performance, and C# Collections are more budget friendly in terms of the used memory. ScienceCode Key Words Page Number Adviser : 902.3.006 : java, C#, collection, performance, analice, framework : 105 : Ass. Prof. Dr. Nursal ARICI vi TEŞEKKÜR Çalışmalarım boyunca değerli yardım ve katkılarıyla beni yönlendiren Hocam Yrd. Doç. Dr. Nursal ARICI' ya , destek ve yönlendirmeleri ile beni her zaman cesaretlendiren Prof. Dr. Ömer Faruk BAY Hocam'a bana her konuda destek veren iş arkadaşlarım Dr. Ayşe OĞUZHAN' a, Arş. Gör. Bayram KÜÇÜK' e, Arş. Gör. Eda AKMAN' a, ailemizin bir parçası olan Vet. Hek. Mahsun KARA'ya ve manevi desteği ile her zaman yanımda olan eşim Dr. Ferhat KARA' ya teşekkürü bir borç bilirim. vii İÇİNDEKİLER Sayfa ÖZET........................................................................................................................... iv ABSTRACT ................................................................................................................. v TEŞEKKÜR ................................................................................................................ vi İÇİNDEKİLER .......................................................................................................... vii ÇİZELGELER LİSTESİ ............................................................................................. ix ŞEKİLLERİN LİSTESİ ............................................................................................... x RESİMLERİN LİSTESİ ............................................................................................. xi KISALTMALAR ....................................................................................................... xii 1. GİRİŞ ..................................................................................................................... 1 2. JAVA COLLECTIONS FRAMEWORK VE .NET FRAMEWORK’ÜN GÖZDEN GEÇİRİLMESİ VE MİMARİSİ.........................4 2.1. Java Collections Framework ........................................................................... 4 2.2. .Net Framework ............................................................................................ 15 2.2.1. .Net framework nedir.......................................................................... 16 2.2.2. .NET framework’teki C# koleksiyonları ............................................ 18 2.2.3. Koleksiyonlar ..................................................................................... 21 2.3. Java Collections Framework Mimarisi ........................................................ 23 2.3.1. Collection framework ......................................................................... 23 2.4. .Net Framework Mimarisi ............................................................................. 25 2.4.1. .NET'in bileşenleri .............................................................................. 26 2.5. Java Virtual Machine Mimarisi ................................................................... 32 2.5.1. Java sanal makinesi ............................................................................ 34 2.5.2. Bir sanal makinenin yaşam süresi ...................................................... 36 2.6. Ortak Dil Çalışma Platformu (CLR-Common Language Runtime) Mimarisi ....................................................................................................... 37 2.6.1. Ortak dil çalışma platformu ............................................................... 39 3. JAVA COLLECTIONS FRAMEWORK VE .NET FRAMEWORK KARŞILAŞTIRILMASI ...................................................................................... 43 Veri Yapıları Açısından C# ve Java'nın Benzerlikleri ve Farklılıkları ........ 43 viii Sayfa 4. JAVA KOLEKSİYONLARI VE C# KOLEKSİYONLARI PERFORMANSINI KARŞILAŞTIRMA UYGULAMA PROGRAMI ............................................... 48 4.1. Programlama Dilleri ve Konseptleri ............................................................. 48 4.2. Java ile Java Collections Framework Performans Uygulama Programı ..... 50 4.3. C# ile .Net Collections Framework Performans Uygulama Programı ......... 53 4.4. Performans Karşılaştırması ........................................................................... 56 4.4.1. Koleksiyonlarda eleman ekleme performans karşılaştırması ............. 57 4.4.2. Koleksiyonlarda sıralama performans karşılaştırması ........................ 70 4.4.3. Koleksiyonlarda arama performans karşılaştırması ........................... 72 4.4.4. Koleksiyonlarda silme performans karşılaştırması ............................ 74 5. SONUÇ ................................................................................................................ 76 KAYNAKLAR .......................................................................................................... 78 EKLER ....................................................................................................................... 81 EK-1 ........................................................................................................................... 82 EK-2 ......................................................................................................................... ..84 EK-3 ........................................................................................................................... 87 EK-4 ........................................................................................................................... 88 EK-5 ........................................................................................................................... 90 EK-6 ........................................................................................................................... 93 EK-7 ........................................................................................................................... 97 EK-8 ........................................................................................................................... 99 EK-9 ......................................................................................................................... 102 ÖZGEÇMİŞ ............................................................................................................. 105 ix ÇİZELGELERİN LİSTESİ Çizelge Sayfa Çizelge 2.1. Arabirimler tanımlama kodu ................................................................... 9 Çizelge 2.2. Arabirimler uygulama kodu .................................................................... 9 Çizelge 2.3. Arabirimler............................................................................................ 10 Çizelge 2.4. Abstract sınıf tanımlamak ..................................................................... 10 Çizelge 2.5. Abstract sınıf uygulamak ..................................................................... 11 Çizelge 2.6. Koleksiyon sınıfları .............................................................................. 12 Çizelge 2.7. C#'ta jenerik ve jenerik olmayan koleksiyonlar ..................................... 22 Çizelge 2.8. Kendi komut satırını yazdıran uygulama ............................................ 37 Çizelge 3.1. C# ve java kodu ................................................................................... 45 Çizelge 3.2. Genişletilemeyen sınıf örneği ............................................................... 45 Çizelge 4.1. Programlama dillerinin karakteristik görünümü ................................... 48 Çizelge 4.2. Kullanılan koleksiyon metotlarının zaman karmaşıklığı ...................... 56 Çizelge 4.3. Kullanılan metotların koleksiyonlarda bulunma durumları ................. 56 Çizelge 4.4. Java programında koleksiyonlara eleman eklenince geçe süre.............. 60 Çizelge 4.5. C# programlama dili için geçen süre .................................................... 62 Çizelge 4.6. Java programlama dili için kullanılan bellek ........................................ 66 Çizelge 4.7. C# programlama dili için kullanılan bellek .......................................... 67 Çizelge 4.8. Java ve C# koleksiyonların sıralama performansları ............................. 71 Çizelge 4.9. Java ve C# koleksiyonların arama performansları ................................. 72 Çizelge 4.10. Java ve C# koleksiyonların silme performansları ................................ 74 Çizelge 4.11. Java ve C# koleksiyonlarının süre bazında karşılaştırılması ............... 75 x ŞEKİLLERİN LİSTESİ Şekil Sayfa Şekil 2.1. Collections framework ................................................................................ 5 Şekil 2.2. Hizmet sınıfları ........................................................................................... 6 Şekil 2.3. JCF ara yüzleri ............................................................................................ 8 Şekil 2.4. JCF abstract sınıflar .................................................................................. 11 Şekil 2.5. Java collections framework çatısı .............................................................. 12 Şekil 2.6. C# koleksiyonu ....................................................................................... 18 Şekil 2.7. NET mimarisi ............................................................................................ 25 Şekil 2.8. .NET programlarının derlenip çalıştırılması ............................................. 26 Şekil 2.9. Kaynak kodun derlenmesi ......................................................................... 38 Şekil 2.10. .Net platformunda yazılıp derlenen bir programın çalışma süreci .......... 41 Şekil 4.1. Java koleksiyonlarına eleman eklenince geçen ortalama süre ................... 61 Şekil 4.2. C# koleksiyonlarına eleman eklenince geçen ortalama süre ..................... 63 Şekil 4.3. Java ve C# koleksiyonlarına eleman ekleyince geçen süre karşılaştırması ............................................................................................ 64 Şekil 4.4. Java koleksiyonlarına eleman eklenince kullanılan bellek ....................... 66 Şekil 4.5. C# koleksiyonlarına eleman eklenince kullanılan bellek .......................... 67 Şekil 4.6. Java ve C# koleksiyonlarına eleman eklenince kullanılan belle karşılaştırması.................................................................................... 68 Şekil 4.7. Java C# ve java programlama dillerinin kullandığı süre ve bellek kullanımları ilişkisini gösteren regresyon eğrisi ............................. 69 Şekil 4.8. Java ve C# koleksiyonlarının sıralama performansları .. ........................... 71 Şekil 4.9. J ava ve C# koleksiyonlarının arama performansları ................................. 73 Şekil 4.10 Java ve C# koleksiyonlarının silme performansları ................................. 74 xi RESİMLERİN LİSTESİ Resim Sayfa Resim 2.1. JVM’inin çalışma prensibi ....................................................................... 34 Resim 2.2. Java sanal makinesinin mimarisi ............................................................. 35 Resim 4.1. Java'da hazırlanan uygulama programı ara yüzü ..................................... 50 Resim 4.2. Java uygulama programı 1.kısım ............................................................. 51 Resim 4.3. Java uygulama programı 2.kısım ............................................................. 51 Resim 4.4. Java uygulama programı 3.kısım ............................................................. 52 Resim 4.5. C#'ta hazırlanan uygulama programı ara yüzü ....................................... 53 Resim 4.6. C# uygulama programı 1.kısım ............................................................... 54 Resim 4.7. C# uygulama programı 2.kısım ............................................................... 54 Resim 4.8. C# uygulama programı 3.kısım ............................................................... 55 xii SİMGELER VE KISALTMALAR Kısaltmalar Açıklama CF Collectins Framework ( Koleksiyon Çatısı) CIL Common Intermediate Language (Ortak Ara Dil) CL .NET Framework Class Library (.NET Sınıf Kütüphanesi) CLI Common Language Infrastructure (Ortak Dil Altyapısı) CLR Common Language Runtime (Ortak Dil Çalışma Zamanı) CLS Common Language Specification (Ortak Dil Tanımları) CPU Central Processing Unit (Merkezi İşlem Birimi) CTS Common Type System (Ortak Tip Sistemi) DLL Dynamic-link library (Dinamik Bağlantı Kitapları) ELF Executable and Linkable Format (Çalıştırılabilir ve Bağlanabilir Biçim) GC Garbage Collector (Çöp Toplayıcısı) IL Intermadieate Language (Ara Dil) ILC Intermadieate Language Code (Ara Dil Kodu) J2SDK Java 2 Software Development Kit (Java 2 Yazılım Geliştirme bbbbbbbbbbbbbbbbbbb Kiti) J2SE Java 2 Platform, Standard Edition (Java 2 Ortamı, Standart bbbbbbbbbbbbbbbbbbbbSürümü) xiii Kısaltmalar Java API Açıklama Java Application Programming Interface (Java Uygulama bbbbbbbbbbbbbbbbbbb Programı Arayüzü) JCF Java Collection Framework (Java Kolleksiyon Çatısı) JDK Java Development Kits (Java Geliştirme Kiti) JIT Just In Time (Anında Derleme) JRE Java Runtime Environment (Java Çalışma Zamanı Ortamı) JVM Java Virtual Machine (Java Sanal Makinesi) MSIL Microsoft Intermediate Language (Mikrosoft Ara Dil) MS Mili Second (Mili Saniye) PE Portable Executable (Taşınabilir Çalıştırılabilir) 1 1. GİRİŞ Java geniş çevrelerce kabul görmüş, işletim sisteminden bağımsız, taşınabilir programlar yazmak için geliştirilmiş, nesneye yönelik bir programlama dilidir [1]. Microsoft Java'ya cevap olarak, .NET ile tam uyumlu ve .NET'in en gözde dili olan C#'ı geliştirdi. C#, C/C++ ve Java'nın güzel yönlerini alıp, nesne yönelimli, bir dil olarak programcıların karşısına çıkmaktadır [2]. Her iki dil de yorumlanarak çalıştırılmaktadır. Yorumlanmadan önce program kodları, Java'da byte koda C#'ta MSIL adı verilen bir ara dile derlenmektedir. Bugün büyük yazılım projelerinin çoğu Java ya da C# programlama dilleri kullanılarak hazırlanmaktadır. Bu yazılım projelerinde kullanılan programlama dili ve kullanılan veri yapıları performansı ve belleği göz ardı etmeyecek derecede etkilemektedir. Projenin esnek, kullanışlı ve performansının yüksek olması kullanıcıların isteği, yazılımcıların da hedefidir. Bunun sağlanabilmesi için değişik performans testleri yapılmaktadır. Koleksiyon tabanlı sınıflar aynı türden yada farklı türden birden fazla nesneyi bir arada tutup, bu nesnelere farklı yollardan erişilmeyi sağlayan veri kaplarıdır. Bu veri kapları güçlü bir uyumluluk ve esneklik sunmaktadır. Java ve C# programlama dillerinin kullandığı koleksiyonların performansları tespit edildiğinde, yazılım projelerinde uygun koleksiyonlar kullanılmakta bu da projelerin esnekliğini ve performansını artırmakta, kullanıcılara zaman ve bellek açısından tasarruf sağlamaktadır. Bu çalışmada, C# ve java programlama dillerinde kullanılan koleksiyonların performansları ve bellek maliyetleri araştırılmıştır. Bu çalışmanın bulguları doğrultusunda, uygulama projesinde kullanılacak koleksiyonların seçimi rahatlıkla yapılabilir. Daha önce de buna benzer çalışmalar yapılmıştır. Literatür taraması yolu ile ulaşılan bazı çalışmalar şu şekilde özetlenebilir. 2007 yılında Mustafa Şahin tarafından, üç farklı dilin (java, python, ruby) çeşitli test uygulamalarındaki çalışma süreleri, bellek tüketimleri ve kod uzunlukları konularında karşılaştırma deneyleri yapılmıştır [3]. Çalışma sonucunda, Java'nın 2 Pyton'a ve Ruby'e göre daha hızlı çalışırken kod uzunlukları açısından daha çok maliyete sahip olduğu gözlemlenmiştir. Belek tüketimi açısından bakıldığında Ruby en az Pyhton en çok belek tüketimine sahiptir. Sean Wentworth ve arkadaşları, C++ standart şablon kütüphanesine karşı Java Collections Framework’ün deneysel bir analizini gerçekleştirmiştir. Analizler, C++'ın performans açısından daha iyi olduğunu gösterir diğer taraftan Java'nın platformdan bağımsız oluşu, esnekliği, güvenli oluşu onu programcılar arasında daha cazip kılmıştır [4]. 2000 yılında Lutz Prechel tarafından yapılan, yedi dili (C, C++, java, Perl, phthon,Rexx, Tcl) çeşitli yönleriyle karşılaştıran bir çalışma mevcuttur. Yazar, çalışmasında 74 farklı yazardan aynı programın 80 versiyonunu, çalışma zamanı performansını, bellek kullanımını, kod uzunluğunu, programlama başarısını ve güvenirliliğini tespit etmek için yazdırmıştır [5]. Cesarini ve arkadaşları IMAP istemci kütüphanelerinin uygulamalarını beş farklı dilde (Erlang, C#, Java, Python, Ruby) karşılaştırmıştır. Kütüphaneler fonksiyonel olarak farklılık gösterdiğinden bu karşılaştırma; Kod satırlarının metris olarak ilkel fonksiyonelliğini, bellek kullanımını ve uygulama zamanlarını içermiştir [6]. 2011 yılında 16 takım arasında farklı programlama dilleri (Java, Perl, Php, Ruby, JavaScript) kullanılarak bir web uygulaması istenmiştir. Ruby gurubu yüksek verimlilik gösterirken Java ve Php gurubu daha az bir verimlilik göstermiştir [7]. Bu çalışma 5 bölümden meydana gelmektedir. Çalışmanın 2. bölümünde Java Collections Framework ve .Net Framework’ün yapısı ve mimarileri incelenmiştir. Java programlama dili Sun firmasının açık kaynak kodlu nesne yönelimli programlama dilidir. Kullanıcılar ücretsiz olarak ulaşabilirler. Bu programlama dili, java sanal makinesi, çöp toplayıcısı gibi mimarilere sahiptir. C# programlama dili Microsoft firmasının ücretli nesne yönelimli programlama dilidir. Bir çok mimarisini Java'dan almıştır. İkisinde de collection framework mevcuttur. 3. bölümünde Java Collections Framework ve .Net Framework'ün karşılaştırılması yapılmıştır. Java ve C# programları arasında benzerlikler ve farklılıklar mevcuttur. 3. 3 bölümde yapılan araştırmalar sonucunda bu iki dilin benzer yönleri ve farklılıkları incelenmiştir. Çalışma kapsamında hazırlanan bütün yazılım 4. bölümde verilmektedir. Bu kısımda uygulamaların çalışma mantığı, uygulamaları çalıştırmak için gerekli programlar, test platformu, elde edilen veriler ve analizleri sunulmaktadır. Performans analizi, ArrayList, LinkedList, Stack, HashSet koleksiyonları üzerinde yapılmıştır. Bu koleksiyonların seçilmesinin nedeni bunların hem java, hem de C#'ta kullanılan koleksiyonlar olmasıdır. Bu şekilde daha sağlıklı bir karşılaştırma yapma imkanı doğmaktadır. İki dilin koleksiyonları arasında karşılaştırma yapılırken bunun yanında bir dildeki kendi koleksiyonları arasında da karşılaştırma yapılmıştır. Hatta bir dildeki bir koleksiyonuna farklı değişken tipleri üzerinde işlem yapıldığında çıkan sonuçlar gözlemlenmiştir. 5. bölümde Java ve C#'ta bulunan koleksiyonların hem kendi aralarında karşılaştırmaları yapıldığında elde edilen sonuçlar verilmiş hem de programlama dilleri açısından karşılaştırılması yapıldığında elde edilen sonuçlar verilmiştir. 4 2. JAVA COLLECTIONS FRAMEWORK VE .NET FRAMEWORK’ÜN bbGÖZDEN GEÇİRİLMESİ VE MİMARİSİ 2.1. Java Collections Framework 2.1.1. Java.util paketi Java Collections Framework, java.util paketinde birbiriyle bağlantılı olan ara yüzler (interfaceler ) ve sınıfların (class) bir karışımıdır [8]. Java.util paketi çok önemli sınıflar barındırır. Özellikle nesne grupları ile çalışmayı sağlayan sınıf koleksiyonları (collections classes) [9]. Java.util paketi iki kısımda incelenebilir; Birinci kısım: Collections Framework’ün bulunduğu kısım. İkinci kısım: hizmet sınıflarının bulunduğu kısım. Bu çalışmada Collections Framework kısmına değinilmiştir. Collections Framework, nesne guruplarını yönetmek için bir teknoloji sunan arabirimler ve sınıflardan oluşan karmaşık bir hiyerarşidir [10]. 5 Şekil 2.1. Collections framework [9] 6 Şekil 2.2. Hizmet sınıfları [9] 7 2.1.2. Collections framework Java’nın orijinal sürümünde Collections Frameworkler yoktu. Java, nesne guruplarını yönetmek ve depolamak için Dictionary, Vector, Stack ve Properties gibi duruma uygun sınıfları kullanırdı. Java’ya J2SE 1.2 ile Collection, Map, Set, List, SortedMap, ve SortedSet interface’lerini ve bunları implement eden sınıflarını barındıran Collections Framework eklendi. Collections Framework’ün diğer önemli sınıfları ve ara yüzleri; Comparator, Collections, Arrays, Iterator, ve ListIterator’dür [9] [10]. Java Collections Framework (JCF), verileri saklamayı, aramayı, silmeyi kısaca verileri kullanırken kolaylık sağlayan bir ambardır. En tepesinde java.util paketi bulunur. Bütün ara yüzler ve sınıflar bu paketin içinde yer alır. JCF ‘de ikisi sıralama için geliştirilmiş temelde 6 tane ara yüz (arabirim, interface) mevcuttur. Bunlar: Collection List Set Map SortedSet SortedMap [8] 8 Şekil 2.3. JCF ara yüzleri 9 2.1.3. Arabirim (Ara yüz, Interface) interface anahtar sözcüğü kullanılarak, bir sınıfın arabirimi onun uygulamasından tamamen özetlenebilir. Yani, interface kullanarak bir sınıfın nasıl yapılacağını değil, ne yapılması gerektiği belirtilebilir. Arabirimler sözdizimi olarak sınıflara benzer, ancak arabirimlerin örnek değişkenleri yoktur ve metotları gövdesiz olarak declare edilir. Bir arabirimin uygulanması için, sınıfın arabirim tarafından tanımlanan metotlarının tümünün uygulaması gerekir. Ancak her sınıf, kendi uygulamasının ayrıntılarının kararını kendisi verir [10]. Arabirim Tanımlamak Çizelge 2.1. Arabirim tanımlama kodu interface BeniCagir { void cagir(int param); } Çizelge 2.2. Arabirim uygulama kodu Class ArabirimKullan implements BeniCagir { // BeniCagir arabirimini uygula public void cagir( int p ) { System.out.println(“cagir “ + p+” parametresi ile cağrıldı.”); }} 10 Çizelge 2.3. Arabirimler [8] Interface Tipi Implement eden Sınıflar Set HashSet, LinkedHashSet, EnumSet SortedSet TreeSet List Vector, Stack, ArrayList, LinkedList Queue PriorityQueue, LinkedList Map SortedMap Hashtable, HashMap, LinkedHashMap, WeakHashMap, IdentityHashMap TreeMap 2.1.4. Abstract class (Özet, Soyut Sınıflar) Alt sınıflar tarafından paylaşılan ve içeriği onlar tarafından doldurulan genel form yapısındaki üst sınıflar Abstract Class olarak oluşturulabilirler. Böyle bir sınıf alt sınıfların gerçekleştirmek zorunda olduğu metotları belirler. Abstract sınıfların nesneleri oluşturulamaz. Abstract metodlar içerdikleri gibi somut metotlar da içerebilirler. Abstract metodlarını alt sınıfı kendi ihtiyacına göre doldurur [10]. Çizelge 2.4. Abstract sınıf tanımlamak abstract class A { abstract void benicagir( ); // Özet sınıflarda somut metodlara da izin verilir void benidecagir() { System.out.println(“Bu somut bir metod.”); } } 11 Çizelge 2.5. Abstract sınıf uygulamak class B extends A { void benicagir() { System.out.println(“B benicagir metodunu implement etti.”); } } class AbstractDemo { public static void main( String args[]) { B b = new B(); b.benicagir(); b.benidecagir(); } } Soyut AbstractCollection, AbstractSet, AbstractList, AbstractMap ve AbstractSequentialList sınıfları, başka somut sınıfları tanımlamak için kullanılan çekirdek yapılardır. Bu sınıflar doğrudan doğruya veri tipi oluşturmak için kullanılmazlar; gereksemeye uyacak biçimde genişletilmeleri gerekir [11]. Collections Framework’teki Abstract Sınıflar Şekil 2.4. JCF abstract sınıflar 12 2.1.5. Koleksiyon sınıfları Collections sınıfı: static metotlar içerir. CF'deki bütün sınıflar bu metotları nesne yaratmadan kullanabilir. Çizelge 2.6. Koleksiyon sınıfları LinkedList TreeSet TreeMap Vector ArrayList HashSet HashMap Stack LinkedHashSet LinkedHashMap PriorityQueue HashTable Şekil 2.5. Java collections framework çatısı 13 Collections Class Collections sınıfı, koleksiyonlar ve map için çalıştırılabilecek kullanışlı static metotlar ve sabitler tanımlar [9]. Koleksiyon terimi, bir java nesneleri topluluğu anlamında kullanılır. Örneğin, ArrayList ambarındaki nesneler topluluğu bir koleksiyondur. Bütün koleksiyon ailesini ifade etmek için koleksiyonlar terimi kullanılır. Collections sınıfı, kendi başına bir veri tipi oluşturmaz. Ama, başka java koleksiyonları üzerinde işlem yapan static metotlara sahiptir. Bu metotlar, sıralama, arama, kopyalama vb. gibi her tipten koleksiyona uygulanan genel işlemleri yaparlar. Collections sınıfının hepsi static olan kırk kadar metodu vardır. Static olmaları nedeniyle, bu metotlar farklı java koleksiyonlarına, nesne yaratmaya gerek kalmadan doğrudan uygulanabilirler [11]. En çok kullanılan metotlardan biri sıralama yapan sort( ) metodudur. Sort( ) metodunun versiyonlarından bir tanesi sıralama yapmak için Comparator kullanır, diğeri doğal sıralamaya dayalı olarak listeleri sıralar [9]. Belirtilen bir liste içinde belirli bir nesne aramak için Binary Search algoritması kullanılır. Listenin sıralı olması gerek aksi taktirde doğru sonuca ulaşılmaz. İlgili metod BinarySearch( ) metodudur. Bir listeye eleman ekleme yapmak için add( ), silmek için remove( ), değiştirmek için set( ), ulaşmak için get( ), elemanları ters çevirmek için reverse( ), elemanları rastgele karıştırmak için shuffle( ), elemanların yerlerini değiştirmek için swap( ), eleman yerleştirmek için put( ) metotları kullanılır. Collections Sınıfının diğer önemli metodları EK-1'de verilmiştir. 14 Interfaceler ve implement eden Sınıflar List Interface Implement eden sınıflar Vector, Stack, ArrayList, LinkedList Set Interface Implement eden sınıflar HashSet, LinkedHashSet, EnumSet SortedSet Interface Implement eden sınıflar TreeSet Map Interface Implement eden sınıflar Hashtable, HashMap, LinkedHashMap, WeakHashMap, IdentityHashMap SortedMap Interface Implement eden sınıflar TreeMap 15 2.2. .NET Framework .Net Framework 2002 yılında yayınlandı. .NET Framework, .NET Framework'ü hedefleyen uygulamaları yöneten bir çalışma zamanı yürütme ortamıdır. Bellek yönetimi ve diğer sistem hizmetlerini sağlayan ortak dil çalışma zamanından ve programcıların uygulama geliştirmenin bütün önemli alanları için sağlam, güvenilir koddan yararlanmalarına imkan tanıyan kapsamlı bir sınıf kitaplığından oluşur. 16 2.2.1. .NET framework nedir? .NET Framework, çalışan uygulamalarına çeşitli hizmetler sağlayan, yönetilen bir yürütme ortamıdır. İki önemli bileşenden oluşur ortak dil çalışma zamanı (CLR), yani çalışan uygulamaları işleyen yürütme motoru; ve .NET Framework sınıf kütüphanesi, yani geliştiricilerin kendi uygulamalarından çağırabilecekleri sınanmış, yeniden kullanılabilir kod sağlayan bir kitaplık. .NET Framework'ün çalışan uygulamalar için sağladığı hizmetler şunları içerir: Bellek yönetimi. Birçok programlama dilinde, programcılar belleği tahsis etme ve serbest bırakmadan ve nesne kullanım ömrü işlemesinden sorumludur. .NET Framework uygulamalarında CLR, uygulama adına bu hizmetleri sağlar. Ortak tür sistemi. Geleneksel programlama dillerinde, temel türler diller arası çalışabilirliği karmaşıklaştıran bir derleyici tarafından tanımlanır. .NET Framework'de, temel türler .net Framework tür sistemi tarafından tanımlanır ve .NET Framework'ü hedefleyen tüm diller için ortaktır. Kapsamlı bir sınıf kitaplığı. Düşük düzeydeki programlama işlemlerini kullanmak için çok büyük miktarda kod yazmak yerine programcılar .NET Framework Sınıf Kitaplığı'ndan alınan tür ve üyelerin erişilebilir kitaplığını kullanabilirler. Geliştirme çerçeveleri ve teknolojileri. .NET Framework; web uygulamaları için ASP.NET, veri erişimi için ADO.NET ve hizmet odaklı uygulamalar için Windows Communication Foundation gibi uygulama geliştirmenin belirli alanlarına ilişkin kitaplıklar içerir. Diller arası çalışabilirlik. .NET Framework'ü hedefleyen dil derleyicileri, ortak dil çalışma zamanı tarafından çalışma zamanında derlenmiş Ortak Ara Dil (CIL) adında bir ara kod üretir. Bu özellik ile, tek bir dilde yazılan yordamlar diğer diller için erişilebilir ve programcılar tercih ettikleri dil veya dillerde uygulamalar oluşturmaya odaklanabilirler. Sürüm uyumluluğu. Nadir istisnalar ile, belirli bir .net Framework sürümü kullanılarak geliştirilen uygulamalar, sonraki bir sürümü üzerinde hiçbir değişikliğe gerek olmadan çalıştırabilinir. 17 Yan yana yürütme. .NET Framework, ortak dil çalışma zamanının birden çok sürümünün aynı bilgisayarda bulunmasına izin vererek sürüm çakışmalarının çözümlenmesine yardımcı olur. Bu da, uygulamaların birden çok sürümünün birlikte var olabileceği ve bir uygulamanın, oluşturulduğu .NET Framework sürümünde çalıştırılabileceği anlamına gelir. Çoklu Sürüm Desteği. .NET Framework Taşınabilir Sınıf Kitaplığı'nı hedefleyerek geliştiriciler, Windows 7, Windows 8, Windows Phone ve Xbox 360 gibi çoklu .NET Framework platformunda çalışan derlemeler oluşturabilir [12]. 18 2.2.2. .NET framework’teki C# koleksiyonları .NET framework veri depolama ve alma için özel sınıfları sağlar. C#'ta iki ayrı koleksiyon türü vardır. Bunlar System.Collections isim alanında bulunan standart koleksiyonlar ve System.Collections.Generic isim alanı altında bulunan jenerik koleksiyonlardır. Koleksiyon, içine nesne alabilen konteynırlardır. Bu konteynırlar güçlü bir uyumluluk ve esneklik sunarlar. .NET’te bütün tiplerin temelinde nesne sınıfı vardır. Koleksiyonlarda saklanan veriler her zaman bir nesne olarak saklanırlar. Yani bir veri koleksiyonda saklandığında bir nesne olarak saklanır geri çekildiğinde tekrar eski tipine dönerek çekilirler. Buna baxing (kutulama) ve unboxing (kutudan çıkarma) denilir [13]. Şekil 2.6. C# koleksiyonu [14] .NET’te bütün tiplerin temelinde nesne sınıfı vardır. Bütün koleksiyonlar, ICollection arayüzünü extend eden IEnumberable arayüzünü ımplement eder. şekil 2.6'da görüldüğü gibi ICollectiondan türeyen IDictionary ve IList, koleksiyonlar için birer arayüzdür. 19 System.Object Nesne sınıfı, bütün tiplerin temel sınıfıdır. Diğer bütün tipler dolaylı yada direkt olarak nesne sınıfından türerler. Nesne sınıfının metotları, özellikleri ve örnek uygulamaları EK-2'de verilmiştir. System.Collections.IEnumerable IEnumerable, kullanıcı tanımlı sınıflar gibi koleksiyon sağlayan bir numaralandırıcı ortaya koyar. Bütün koleksiyonlar, ICollection tarafından genişletilmiş IEnumerable arayüzünü implement (uygular) eder. IEnumerable arayüzünün metotları, özellikleri ve örnek uygulamaları EK-3'de verilmiştir. System.Collections.ICollection Icollection arayüzü jenerik olmayan kolleksiyonların eleman sayılarına ulaşmak ve onları yönetmek için metodlara sahiptir. System.Collections isim alanındaki sınıflar için temel bir arayüzdür. ICollection arayüzünün metotları, özellikleri ve örnek uygulamaları EK-4'de verilmiştir. ICollectiondan türeyen iki interface mevcuttur: IList ve IDictionary ICollectiondan türeyen diğer koleksiyonlar System.Collections.BitArray System.Collections.Stack System.Collections.Queue System.Collections.Specialized.NameValueCollection System.Collections.IList IList, ICollection interface'inden türer. Add, Clear, Contains, IndexOf, Insert, Remove, RemoveAt gibi en çok kullanılan koleksiyon metotlarını barındırır. Ayrıca 20 indeksleyici içerir. IList arayüzünün metotları, özellikleri ve örnek uygulamaları EK-5'te verilmiştir. IList arayüzünü uygulayan koleksiyonlar System.Array System.Collections.ArrayList System.Collections.Specialized.StringCollection System.Collections.IDictionary ICollection interface'inden türer. Koleksiyonları anahtar değer ikilisi olarak sunar [14]. IDictionary arayüzünün metodları, özellikleri ve örnek uygulamaları EK-6'da verilmiştir IDictionary arayüzünü uygulayan koleksiyonlar System.Collections.Hashtable System.Collections.Specialized.ListDictionary System.Collections.SortedList System.Collections.Specialized.HybridDictionary 21 2.2.3. Koleksiyonlar Koleksiyon tabanlı sınıflar aynı türden yada farklı türden birden fazla nesneyi bir arada tutup bu nesnelere farklı yollardan erişilmeyi sağlarlar. Bütün koleksiyon sınıfları System.Collections isim alanında bulunurlar. Bir koleksiyon nesnesi içinde bulunan elemanlara foreach döngüsü ile erişilmesi mümkündür. Bu erişim, koleksiyon tabanlı sınıfların IEnumarable arayüzünü uygulamış olmasının bir sonucudur [2] [14]. System.Collections isim alanındaki koleksiyonlar Array, ArrayList ,BitArray, HashTable, SortedList ,Queue, Stack, IEnumerable, ICollection, IList, IDictionary, CollectionBase, ReadOnlyCollectionBase, DictionaryBase System.Collections.Generic isim alanı altında bulunan jenerik koleksiyonlar, daha esnek ve veriler ile çalışıldığında daha çok tercih edilenlerdir. Jenerik koleksiyonlar diğer bir adıyla Jenerikler .NET Framework 2.0 ile tanıtıldı. Jenerikler tip güvenliğini, performansı ve genelliliği bir arada sunar. .NET Framework, System.Collections.Generic isim alanı içerisinde bir dizi jenerik nesne içerir [13]. Bunlar; System.Collections.Generic isim alanı içerisindeki jenerik koleksiyonlar List<T>, LinkedList<T>, Dictionary<TKey, TValue>, SortedList<TKey, TValue> SortedDictionary<TKey, ICollection<T>, TValue>, IList<T>, ReadOnlyCollection<T> Queue<T>, IDictionary<TKey, Stack<T>, TValue>, IEnumerable<T>, Collection<T>, 22 Çizelge 2.7. C#'ta jenerik ve jenerik olmayan koleksiyonlar System.Collections System.Collections.Generic Non Generic Generic Karşılığı Array ArrayList List<T> BitArray - - LinkedList<T> HashTable Dictionary<TKey,TValue> SortedList SortedList<TKey,TValue> - SortedDictionary<TKey,TValue> Queue Queue<T> Stack Stack<T> IEnumerable IEnumerable<T> ICollection ICollection<T> IList IList<T> IDictionary IDictionary<TKey,TValue> CollectionBase Collection<T> ReadOnlyCollectionBase ReadOnlyCollection<T> DictionaryBase - - HashSet<T> 23 2.3. Java Collections Framework Mimarisi 2.3.1. Collections framework Java’nın orijinal sürümünde Collections Frameworkler yoktu. Java, nesne guruplarını yönetmek ve depolamak için Dictionary, Vector, Stack ve Properties gibi duruma uygun sınıfları kullanırdı. Java’ya J2SE 1.2 ile Collection, Map, Set, List, SortedMap, ve SortedSet interface’lerini ve bunları implement eden sınıflarını barındıran Collections Framework eklendi. Collections Framework’ün diğer önemli sınıfları ve ara yüzleri; Comparator, Collections, Arrays, Iterator, ve ListIterator’dür [9] [10]. Java Collections Framework (JCF), verileri saklamayı, aramayı, silmeyi kısaca verileri kullanırken bize kolaylık sağlayan bir ambardır. En tepesinde java.util paketi bulunur. Bütün ara yüzler ve sınıflar bu paketin içinde yer alır. JCF ‘de ikisi sıralama için geliştirilmiş temelde 6 tane ara yüz (arabirim, interface) mevcuttur. Bunlar: Collection List Set Map SortedSet SortedMap [8] Java Collection Framework mimarisi içerisinde en tepede tanımlanmış bir interface olan Collection arabirimi, mimarinin tüm arabirimlerini oluşturmaktadır. Yani Collection Framework' un temelini Collection tutmaktadır. Collection, bir takım nesneleri depolamak ve kullanmak için kendini uygulayan bir çok sınıfa esnek metotlar sağlar [15]. 24 interface Collection <E> Framework' ün tüm arabirimleri jenerik olduğu için Collection arabirimi de <E> jenerik tipi ile depolanacak nesnelerin tipini belirtir. Java Collection Framework mimarisinin temelini oluşturan bu arabirimin metotları ise aşağıda verilmektedir [16]. boolean add(E e), bir koleksiyon'a E tipli nesne ekler. Eğer ekleme başarılı ise true döner. boolean addAll(Collection c), bir koleksiyon'a elemanları E tipinden türemiş başka bir c collection' nın tüm elemanlarını ekler. İşlem başarılı ise true döner. void clear(), koleksiyon'nun tüm elemanlarını kaldırır ve koleksiyon'u sıfırlar. boolean contains(Object o), koleksiyon içerisinde o nesnesinin varlığını araştırır. Şayet bulursa true döner. boolean containsAll(Collection c), koleksiyon içerisinde, c koleksiyon'un tüm elemanlarının varlığını denetler. Şayet tüm elemanlar koleksiyon içerisinde var ise true döner. boolean isEmpty(),koleksiyon da hiç bir eleman yok ise true döner. Iterator iterator(), koleksiyon'nun elemanlarına erişen bir iteratör döndürür. boolean remove(Object o), koleksiyon'dan ilgili o nesnesini kaldırır. boolean removeAll(Collection c), koleksiyon'dan c koleksiyon'un elemanlarına eş değer tüm elemanları kaldırır. boolean retainAll(Collection c), c koleksiyon'un elemanlarına eş değer elemanların haricindeki tüm nesneleri kaldırır. int size(), koleksiyon eleman sayısını döndürür. Object[] toArray(), koleksiyon elemanlarını bir nesne dizisinde döndürür. T[] toArray(T[] a), a dizisinin tipiyle eşleşen koleksiyon elemanlarını jenerik tipte bir dizi ile döndürür. 25 2.4. .Net Framework Mimarisi .NET Framework, yeni nesil uygulamaların ve XML web hizmetlerinin yapılandırılmasını ve çalışmasını destekleyen bir teknolojidir. Bu teknoloji çok katmanlı ve dağıtık uygulama geliştirme modellerini benimsemiştir. C# C++ Jscript VB. NET J# … Temel Dil Tanımları (Common Language Specification CLS) ASP. NET Windows Formları Web Formları + Web Servisleri Mobil İnternet Araçları ADO.NET ve XML Temel Sınıflar ve Kütüphaneler Ortak Dil Çalışma Platformu (Common Language Runtime CLR) İşletim Sistemleri (Operation Sistem OS) Şekil 2.7. .NET mimarisi [2] [17] .NET’ in en önemli yapıtaşı, Framework olarak belirtilebilir. Bu yapı, kendini 2 önemli alt bileşene ayırır. Bunlar; CLR(Common Language Runtime - Ortak Dil Çalışma Platformu) ve CL (.NET Framework Class Library). CL içinde uygulama geliştirilirken kullanılan kütüphaneler bulunmaktadır. Formlar, nesneler ve kontroller hep bu yapı içinde yer alır [18]. .NET’in çalışma mantığı Java’nınkine oldukça benzer. .NET, kodu önce IL’ye (Aradil) derler ve bu IL kodu çalıştırılmak istendiği zaman .NET CLR, JIT derleyicilerini kullanarak makine diline çevirir. CLR makine diline çevrilmiş 26 program kodunu önbellekte tutar. Bu büyük performans artışına sebep olurken sistemin hafızasında küçümsenmeyecek miktarda yer kaplar [2]. 2.4.1. .NET’in bileşenleri .NET bileşenleri şu şekilde sıralanabilir CLR (Common Language Runtime - Ortak Dil Çalışma Platformu) CTS (Common Type System - Ortak Tip Sistemi) CLS (Common Language Specification - Ortak Dil Tanımları) IL (Intermadieate Language - Ara Dil) JIT (Just In Time - Anında Derleme) CL(.NET Framework Class Library - .NET Sınıf Kütüphanesi ) CLR (Ortak dil çalışma platformu) CLR, programlama dillerinin entegrasyonu (language integration), güvenlik (security), bellek (memory), süreç (process) ve iş parçacığı (thread) yönetimi gibi çalışma zamanı servislerinden sorumludur. .NET alt yapısında programların çalışmasını kontrol eden ve işletim sistemi ile programlar arasında yer alan arabirim görevini üstlenir. CLR bunun yanı sıra geliştirme zamanında tip güvenliğinin sağlanması gibi bazı rollere sahiptir. CLR C# Program Kodu MSIL Assembly Diğer dll ve COM bileşenleri .NET temel sınıf kütüphanesi Şekil 2.8. .NET programlarının derlenip çalıştırılması [2] Çalıştırılabilir makine kodu 27 .NET programlarının derlenip çalıştırılması C# kodları, C++ veya Visual Basic gibi direkt makine koduna derlenmezler. Önce IL (Microsoft Intermediate Language - Microsoft ara dili) denilen bir ara koda derlenir ve uzantısı exe'dir. Bu dosya çalıştırılmak istendiğinde ise .Net Framework'teki CLR devreye girer ve IL kodu makine koduna dönüştürür, böylelikle artık kodu bilgisayar anlayabilir. Burada oluşturulan assembly herhangi bir sistemde (Linux veya MAC OS) CLR tarafından çalıştırılır. .Net Framework'teki CLR, oluşturduğu makine kodlarını geçici bir süreliğine belleğe koyar, eğer aynı kodlar tekrar çalıştırılmak istenirse tekrar IL koddan makine koduna dönüşüm yapmak yerine bu belleğe kaydettiği makine kodlarını kullanır. Bu yüzden oluşturulan programlar ilk çalıştırıldığında program biraz yavaş çalışabilir, ancak daha sonraki çalışmalarda oldukça hızlanır. C#'ta kodun direkt makine kodu yerine, önce IL koda çevrilmesi platformdan bağımsızlığı sağladığı için avantajdır. Çünkü makine kodu taşınabilir değildir. Programları direkt makine koduna derlediğimiz zaman ilgili programın belirli bir işletim sistemine göre derlenmesi gerekir. Halbuki IL kod taşınabilirdir, ortak bir koddur, işletim sistemlerindeki çeşitli programlar vasıtasıyla makine koduna dönüştürülebilir. Örneğin Windows'ta bu işi .Net Framework yaparken, Linux'ta Mono yapabilir. CTS (Common Type System - Ortak Tip Sistemi) CLR içerisine inşa edilmiş güçlü ve zengin bir tip sistemidir. Çoğu programlama dilinde bulunan tipleri ve bu dillerin operasyonlarını desteklemektedir. Birçok programlama dilinde bulunan tiplerin CTS (Ortak tip sistetemi) içerisinde gerçekleştirimi yapılmış durumdadır. CTS'de, veri tipleri iki ana kısma ayrılır. Bunlar: değer (value) ve referans (reference) tipleridir. CTS aşağıdaki fonksiyonları bize sunar; 28 .NET mimarisinde tip güvenli, yüksek performanslı ve kullandığımız programlama dilinin/dillerinin diğer .NET uyumlu diller ile entegre bir şekilde çalışmasını sağlar. Birçok programlama dilinin .NET mimarisinde tam nesne yönelimli olarak .NET için program yazma aracı olmasına imkan verir. Herhangi bir .NET uyumlu dilde geliştirilen nesnenin diğer dillerden de sorunsuz olarak çağrılabilmesini garantiler [2]. CLS (Common Language Specification - Ortak Dil Tanımları) CLS, bünyesinde barındırdığı birtakım yapıları ve kısıtları ile kütüphane(library) ve derleyici(compiler) yazabilmek için rehberlik yapmaktadır. CLS, CTS'nin bir altkümesidir. CLS uygulama geliştiriciler için büyük önem arz etmektedir. Öyle ki bir uygulama geliştirici yazdığı kodun diğer kod geliştiriciler tarafından da kullanılabilir olmasını göz önünde bulundurmalıdır. CLS'nin kriterleri ve kuralları göz önünde bulundurularak yazılan bir API(Application Program Interface), diğer programlama dilleri içerisinden kullanılabilmekte, Common Language Runtime tarafından da işletilebilmektedir. IL (Intermediate Language – Aradil) IL işlemciden bağımsız komut setinden oluşmaktadır. Bu komut seti içerisinde nesnelerin yüklenmesi, depolanması ve initialize edilmesini sağlayan komutların yanı sıra aynı zamanda nesneler üzerinde metod çağrımını sağlayan komutlar da yer almaktadır. .NET Framework ile yazılmış bir kaynak kodun derlenmesi sonucu IL kodu oluşmaktadır. IL, Metadata ve CTS sayesinde .NET dilleri arasında bir bütünleşme sağlanmaktadır. Metadata, programda kullanılan verilerin tiplerinin yanında oluşturulan sınıfların metotlarını ve bunların özelliklerini ve diğer bilgileri içerir. Metadata’nın içeriği çalışma zamanında JIT derleyicileri tarafından kullanılır [2]. IL kodun çalıştırılmasından önce var olan IL kodu doğal makine koduna (native code) dönüştürülmektedir. 29 JIT derleyicileri JIT, CLR içinde bulunan bir derleyicidir. MSIL kodu CLR içindeki JIT ile derlenip makine koduna dönüşmektedir. JIT, MSIL’ i derledikten sonra dönüşen makine kodunu, hafızaya yükler. Yazılım çalışmaya başlar. Bir defa bu noktaya gelen kod, sonraki çağırımlarda buradan kullanılır. Bu yüzden, uygulamaların ilk defa çalıştırılması her zaman yavaş olmakta, sonraki çağırımlar ise daha hızlı gerçekleşmektedir. Microsoft .NET'te üç tip JIT derleyicisi mevcuttur. Pre-JIT derleyici: pre-JIT derleyicisi tüm program kodunu makine koduna çevirdikten sonra çalıştırır. Bu şekilde programların çalışması daha hızlı olmaktadır. Bu derleme türü büyük sistemlerin verimliliğini artırırken beraberinde daha fazla bellek gerektirir. Normal-JIT derleyici: Varsayılan olarak kullanılan bu derleme çeşidi, program kodunu derledikten sonra derlenen kodu ön bellekte depolar. Eğer program kodunun bir kısmı çalışma anında çağrılırsa ön bellekte depolanan derlenmiş kod yürütme için kullanılır. Eco-JIT derleyici: Az miktarda hafızaları ve ön bellekleri olan sistemler için uygun olan bir derleme çeşididir. Program kodu çalışma anında çağrıldığında derlenirler. Fakat kullanılabilir hafıza belli bir oranın altına düştüğünde, daha önceden derlenmiş ve çalıştırılmış kısımlar silinir. Bu sayede sistemde bellek sorunlarının yaşanması engellenmiş olur. Silinen derlenmiş kısımlar tekrar çağrıldığında ise aynı kodlar tekrar derlenmek zorunda kalınır. Bu da programın daha yavaş çalışmasına neden olur. 30 CL(.NET Framework Class Library - .NET Sınıf Kütüphanesi ) Temel sınıflar; giriş/çıkış, string işlemleri, güvenlik yönetimi, ağ iletişimi, thread yönetimi, metin işleme ve kullanıcı ara yüz tasarımı gibi standart fonksiyonları kapsamaktadır. ASP.NET sınıfları web tabanlı uygulamalar ve web servisleri geliştirebilmek için destek sağlamaktadır. Windows Forms sınıfları ise masaüstü uygulamaları geliştirebilmeyi sağlamaktadır. Sınıf kütüphaneleri, .NET Framework dilleri arasında ortak, tutarlı bir geliştirme ara yüzü sağlamaktadır. .NET Framework koleksiyon sınıfları kendi koleksiyon sınıflarınızı geliştirmek için kullanabileceğiniz bir arabirim kümesi uygular. Koleksiyon sınıfları .NET Framework sınıfları ile sorunsuz olarak birleşir. .NET Framework, aşağıdaki türde uygulamalar ve hizmetler geliştirmek için kullanılabilir: Konsol uygulamaları Windows GUI uygulamaları (Windows Forms) Windows Presentation Foundation (WPF) uygulamaları. ASP.NET uygulamaları. Windows hizmetleri. Windows Communication Foundation (WCF) kullanan hizmet odaklı uygulamalar. Windows Workflow Foundation (WF) kullanılarak iş akışı etkin uygulamalar. Assembly kavramı .NET platformu için yazılan bütün kodların sonucunda oluşan exe ve dll uzantılı dosyalara genel olarak assembly denmektedir. Projeye ait derlenmiş kodlar ve metadata diye adlandırılan öz niteleyici kodlar Assembly içerisinde bulunurlar. Assembly’lerin özellikleri kısaca aşağıdaki gibi sıralanabilir. Assembly’lerin içerisinde yer alan metadata olarak adlandırılan veriler Assembly’deki tür bilgilerini ve başka kaynaklarla olan bağlantıları saklarlar. 31 Assembly’de (dll yada exe) versiyon bilgisi tutulur. Klasik dll ve exe tipi dosyalarda versiyon bilgisi saklanmadığı için çeşitli uyumsuzluklar yaşanabilmekteydi. Mesela farklı iki firmanın hazırladığı dll’ler aynı isimli olduğunda sonradan register edilen dll, halihazırda bulunan dll’in üzerine yazıldığı için sistemde bulunan bazı uygulamalarda sorun çıkarırdı. Dll’ler bu tür sorunlara yol açtığı için DLL Hel (Dll Cehennemi) kavramı ortaya çıkardı. Aslında COM dll’leri ile bu sorun bir nebze ortadan kalkmışsa da asıl çözüm Assembly’ler ile gelmiştir. Assembly’lerde versiyon bilgisi saklandığı için bir uygulama içerisinde farklı versiyonlara sahip Assembly’ler kullanıbilinir. Program kurma işlemi, Assembly’ye ilişkin dosyayı direkt kopyalayarak yapılabilir (Eski sistemde DLL’lerin kayıt (register) edilmesi gerekiyordu) [2]. 32 2.5. Java Sanal Makine (JVM-Java Virtual Machine ) Mimarisi Java Sanal Makinesinin daha iyi anlaşılması için bazı önemli terimler aşağıda açıklanmıştır. Java development kit (JDK) Bu bütün temel java framework paketlerini içermekte, Java derleyicisini, JRE, JVM, debugger, Java Interpreter'ı, Java api kütüphanelerini, geliştirici tool’ları kısacası java programını geliştiren, hatalarını bulan, derleyen ve çalıştıran her şeyi içerir [19]. Java runtime environment (JRE) Her hangi bir Java uygulamasını çalıştırmak için gerekli minimum gereçleri içerisinde barındıran bir yapıya sahiptir. Bir Java uygulaması çalıştırılmak istendiğinde , öncelikle sahip olunması gereken platform JRE’dir. JRE her işletim sisteminde farklılık gösterir. Ayrıca JRE içerisinde JVM de bulunur [19] [20]. Just in time (JIT) Anında derleme denilen JIT, bytecode’u sanal makinenin kurulu olduğu gerçek sistemin diline anında derleme yaparak dönüştürür. Bu sayede verimde ciddi artışlar sağlanır. Fakat 2000 yılından sonra geliştirilen sanal makinelerde (HotSpot gibi) JIT’in işlevi sanal makinelerde yer almaya başladı. Java API Java API, Java yazılımlarında kullanılan yazılım kütüphanelerine genel olarak verilen isimdir. Java API ile disk, grafik, ağ, veri tabanı, güvenlik gibi yüzlerce konuda kullanıcılara erişim imkânı sunulur. Java API J2SDK'nın bir parçasıdır [20]. Atık veri toplayıcı (Garbage Collection) Atık veri toplama teknolojisi Java'dan önce de var olan ama Java ile adını duyurmuş ve yaygın olarak kullanılmaya başlanmış bir kavramdır. C++, C gibi dillerin en büyük engellerinden birisi dinamik bellek yönetimidir. Yazılımda gösterici (işaretçi pointer) kullanılarak dinamik olarak bellek ayrıldıktan sonra o bellek ile işlem 33 bittiğinde mutlaka ayrılan belleği bellek yöneticiye özel altyordamlar yardımıyla (delete, free vs.) iade edilmesi gerekir. Yoksa bellek sızıntısı (memory Leak) oluşur ve bu bir süre sonra yazılımın ve işletim sisteminin beklenenden farklı davranmasına yol açabilir. Sızıntıların saptanması oldukça güçtür ve bulunması zor hatalara yol açar. Bu nedenle bugünün tüm büyük C ve C++ yazılımları az da olsa bellek sızıntısı içerir (işletim sistemleri dahil). Atık veri toplayıcı sayesinde Java'da bir nesne oluşturulduktan sonra o nesne ile işlem bittiğinde hiçbir şeyin yapılması gerekmez: Sanal makine akıllı bir biçimde kullanılmayan bellek bölümlerini belirli aralıklarla ya da uyarlamalı yöntemlerle otomatik olarak temizler ve sisteme iade eder. Bu işleme çöp toplama (garbage collection) adı verilir. Çöp toplama sistemlerinin yapısı oldukça karmaşıktır ve geçen yıllar içinde büyük gelişmeler kaydedilmiştir. Çöp toplayıcının varlığı Java'da bellek sızıntısı olmayacağı anlamına gelmez, ama bellek sızıntılarına daha ender olarak ve farklı şekillerde karşılaşılır. Genellikle tedavi edilmesi daha kolaydır [19]. 34 2.5.1. Java sanal makinesi JVM (Java Virtual Machine – Java Sanal İşlemcisi) C++ dilinde yazılmış bir programdır. Bir Java programı javac.exe ile derlendikten sonra byte code ismi verilen bir ara sürüm oluşur. Byte code, ana işlem biriminin (CPU – Cental Processing Unit) anlayacağı cinsten komutlar ihtiva etmez, yani klasik Assembler değildir. Java byte code sadece JVM bünyesinde çalışır. JVM, derlenen Java programı için ana işlemci birimi olma görevini üstlenir. Bu özelliğinden dolayı Java programlarını değişik platformlar üzerinde çalıştırmak mümkündür [20]. Her platformun kendine özgü bir sanal makinesi yani JVM si vardır. JVM'ler her platform için farklı olsa bile aynı Java kodunu çalıştırırlar. Bundan dolayıdır ki; programcının yazdığı bir java kodu, platforma bağlı olmadan JVM sayesinde her ortamda çalışır [19]. Bu sebepten dolayı Java “write once, run anywhere – bir kere yaz, her yerde koştur.” unvanına sahiptir. Resim 2.1. JVM’inin çalışma prensibi [19] Şekil yorumlanacak olursa; java program kodu yazılır. ( MyProgram.java ) Bu kaynak kod " javac compiler (derleyici) " ile dernelerek ikili koda ( byte kod'a ) çevrilir ve .class uzantılı dosyalar oluşturulur. ( MyProgram.class ) JVM, oluşturulan bu byte kodları yorumlar ve işlemcinin anlayacağı makine diline (0100010..) çevirir [19]. JVM’nin Java platformunun nesne modüllü (object module) formatı olan class uzantılı sınıf dosyalarının belleğe yüklenip çalıştırılması için gereken hizmetleri sunan bir sistem programı olduğu ve temel görevinin sınıf dosyalarını yorumlamak olduğu yukarıda söylendi. Ancak, JVM’yi salt bir yorumlayıcı değildir. Zira, yorumlama ile birlikte JVM'nin şu görevleri de vardır. 35 Belleğe yükleme ve çalıştırma sırasında güvenlik denetimlerinin yapılması Sınıf dosyalarının çalıştırılması esnasında yığın bellekte oluşabilecek çöplerin toplanması Yorumlamanın getirdiği çalışma hızındaki düşüşü azaltmak amacıyla kodun anında derleme kullanılarak daha hızlı çalıştırılması JVM’nin diğer bir özelliği, programcıların daha hızlı kod geliştirmelerine olanak tanıyan çöp toplama birimidir. JVM'nin bir parçası olarak gerçekleştirilen çöp toplayıcı, yığın bellekte kullanılmaz hale gelen bölgelerin geriye döndürülmesini sağlar [21]. Bu da programcılara zaman kazandırır. Resim 2.2. Java sanal makinesinin mimarisi [21] 36 2.5.2. Bir sanal makinesinin yaşam süresi Java uygulaması başladığı zaman, bir çalışma zamanı örneği doğar. Uygulama tamamlandığında, örnek ölür. Eğer üç java uygulaması aynı anda, aynı bilgisayarda ve aynı somut uygulamada başlatılırsa, o zaman üç java sanal makinesi de çalışmaya başlar. Her java uygulaması kendi java sanal makinesi içinde çalışır. Bir java sanal makinesi örneği ilk sınıfın main() metotunu çağırarak çalışmaya başlar. Bu main() metot ; statik, public, void olmak zorunda ve bir string dizisini parametre olarak döndürmek zorundadır. Böyle bir main() metot java uygulaması için başlangıç noktası olarak kullanılır [22]. Çizelge 2.8. Kendi komut satırını yazdıran uygulama class Echo { public static void main(String[] args) {int len = args.length; for (int i = 0; i < len; ++i) { System.out.print(args[i] + " "); } System.out.println(); } } 37 2.6. Ortak Dil Çalışma Platformu (CLR-Common Language Runtime) Mimarisi Ortak Dil Çalışma Platformunun daha iyi anlaşılması için bazı önemli terimler aşağıda açıklanmıştır. Assembly Derlemiş IL koduna assembly denir. Com interop services VB 6.0, C++ gibi uygulamaların çağrılmasını sağlayan servistir. Maneged code (yönetilen kod) .NET framework tarafından yönetilen ve makine koduna dönüştürülmeden önce ara bir dile çeviren kod bloğudur. C# .net, J# .net, VB.net, C++.net ile yazılan kodlar MANAGEDbCODE’dur. Unmanaged code (Yönetilemeyen Kod) CPU tarafında direk çalıştırılan ve bir framework(virtual machine) tarafından yönetilmeyen kod blogudur. VB 6.0, C++, C ile yazılan kodlar UNMANAGED CODE’dur. Microsoft intermediate language (MSIL) Visual Studio .Net içerisindeki tüm dillerde yazılmış kodların derleme sonucunda dönüştürüldüğü ortak çıktının oluşturulduğu dildir. Metadata Programda kullanılan veri tiplerinin yanında oluşturulan sınıfların metotlarını ve bunların özelliklerini ve diğer bilgilerini içeren bir birimdir. Metadata'nın içeriği çalışma zamanında JIT derleyicileri tarafından kullanılır. 38 Portable executable (PE) .NET, Mono ve Rotor gibi CLI (Common Language Infrastructure) standartlarına uygun ortamlardaki assembly dosyaları PE (Portable Executable) dosya formatını kullanmaktadır. PE dosya formatı Microsoft’un 32 ve 64 bit Windows sistemlerinde kullandığı genel amaçlı çalıştırılabilir (executable) bir formattır. Bu format tıpkı UNIX/Linux sistemlerinde kullanılan ELF (Executable and Linkable Format) gibi bölümlerden (sections) oluşur. Bölümlerin içerisinde programın yüklenmesi ve çalıştırılabilmesi için gerekli bilgiler vardır. Source code Bilgisayar 0’lar ve 1’lerden anlayan bir makinedir. Bir arayüz kullanarak yazılan kodlara kaynak(soruce) kod adı verilir. Native code Kaynak kodların derlenerek makinenin anlayacağı şekle dönüşmüş haline native code adı verilir. Compile Kaynak kodların, makinenin anlayacağı dile veya bir ara dile dönüştürülmesi işlemine compile(derleme), bu işlemi gerçekleştiren araca da compiler(derleyici) adı verilir. Şekil 2.9. Kaynak kodun derlenmesi [25] 39 Compile time Yazılmış olan uygulamanın CIL(Common Intermediate Language) çevrildiği zaman sürecidir. Her hangi bir dil de yazılmış .Net uygulaması, her dile ait derleyiciler ile ortak bir dile CIL(Bytecode) çevrilir. Run time Uygulamanın çalıştığı süreçtir, Compile Time da oluşturulan ByteCode’lar CLR(Common Language Runtime) ile satır satır yorumlanarak (Interpreter) makine diline çevrilir ve uygulamanın çalışması sağlanır [23]. 2.6.1. Ortak dil çalışma platformu (CLR) CLR, C# ile üretilmiş kodların sistem üzerinde çalıştırılmasını sağlayan mekanizmadır. Bir C# kodu yazılıp derlendiğinde bu kod Microsoft Intermediate Language (MSIL) 'a dönüştürülür. MSIL kodları Portable Executable denilen bir dosyada saklanır. Bu derleme sonucunda program her platformda çalıştırılabilinir yapıya kavuşur. MSIL'in temelini Assembly oluşturur. Assembly, MSIL içindeki paylaşılan ve tekrar kullanılabilen temel bir birimdir. Assembly'ler, ASP.NET sayfası, PE dosyası, image dosyası, VB.NET kaynak dosyası gibi tek bir dosya olabileceği gibi bunların bir veya daha fazlasını da barındıran bir yapıda olabilir. MSIL ile derleme yapıldığında assembly'le birlikte, programa ait bir takım açıklayıcı bilgiler oluşturulur. Buna Metadata denir. Bu bilgiler programa yönelik ve dışarıya verilecek her türlü bilgiyi kapsar [19]. MSIL çalıştırılabilir bir kod değildir. Bu kod " sözde kod " (pseudocode ) içeren bir dosyadır. Bu kod anca bulunduğu sistemde bir ara program ile çalıştırılır. Bu program MSIL'i, sistem üzerinde çalıştırır. İşte C#'ta bu CLR 'dir. Yani CLR 'nin olduğu her ortamda (işletim sistemi ve işlemci fark etmeksizin) C# da derlenmiş kodlar daha doğrusu MSIL çalışacaktır. Program çalışacağı zaman C# ile derlenen kodlar yani MSIL kodlar; bir JIT (Just-InTime - Tam zamanında) derleyici tarafından kullanılarak çalıştırılabilir koda dönüştürülürler. C# (veya .NET) kodları çalıştırıldığı zaman CLR, bu JIT derleyiciyi 40 çalıştırır. JIT derleyici programın ihtiyaçıına göre MSIL 'i yerel dile çevirir. Yani MSIL olarak üretilen her kod CLR'nin olduğu her ortamda o sisteme uygun bir dile çevrilir ve yürütülür. Bu kodun içinde yer alan metadata olarak tanımlanan çıktı bulunur. Bu çıktı sayesinde programın diğer kodlarla etkileşimi sağlanır. CLR, programları değişik şekilde derleyebilir. Varsayılan derleme türü JIT(Just IN TIME- çalışam anında derleme) 'dır. Program çalışırken daha önce derlenmemiş bir parçasına gelince hemen o kısmı da derler ve bunu hafızda chach'e koyar. Tekrar aynı program parçasını çalıştırmak gerekirse burayı hafızadan çalıştırır. Eğer RAM yeteri kadar büyükse, programın tamamı derlenmiş ve hafızada depolanmış durumda olabilir. Bu durumda program daha hızlı çalışır. Hafızanın yeteri kadar büyük olmadığı durumlarda EconoJIT (Ekonomik JIT) derleyicisi kullanılabilir. Bu derleyici ile programın derlenmiş kısımları hafızada depolanmaz ve her seferinde aynı program parçası derlenir. Tabi ki bu derleyici normal JIT'e göre programları daha yavaş çalıştırır. Ama RAM 'i çok daha az kullanır. CLR ile gelen üçüncü derleyici PreJIT(ön JIT derleyicisi) ise derleme işini program çalışmadan önce yapar ve tüm makine kodlarını bir yerde saklar. Çalışma anında çok hızlı olan program diğer JIT derleyicileriyle derlenmiş olanlara nazaran çok hızlı çalışır. Kısaca C# kodu iki defa derleme aşamasından geçer program kodu MSIL'e, MSIL ise makine koduna çevrilir [24]. 41 Şekil 2.10. .Net platformunda yazılıp derlenen bir programın çalışma süreci [23] Çalışma zamanı, aşağıdaki avantajları sağlar Performans iyileştirmeleri. Diğer dillerde geliştirilen bileşenleri kolayca kullanma yeteneği. Sınıf kitaplığı tarafından sağlanan genişletilebilir türler. Devralma, arabirimler ve nesne tabanlı programlama için aşırı yükleme gibi dil özellikleri. Çok iş parçacıklı ve ölçeklenebilir uygulamaların oluşturulmasını sağlayan açık ve serbest iş parçacığı oluşturma desteği. Yapılandırılmış özel durum işleme desteği. Özel öznitelikler için destek. Çöp toplama. Artan tür güvenliği ve emniyeti için işlev işaretçileri yerine delegeler kullanma [26]. Debugging Yazılan programların sıfır hata ile yazılması imkansızdır. Boyutu değişken olmakla birlikte mutlaka hatalarla karşılaşılır. Zaten bu sebepten dolayı projelerin en önemli aşamalarından biri de bakım aşamasıdır. İşte yazılımlar içerisinde ortaya çıkan bu hatalara bug adı verilir. Debug kelimesi de hata ayıklamak olarak düşünülebilinir. Çalışan bir programın çalışmasının adım adım izlenilebilinmesi ve bu esnada 42 istenilen sonuçların elde edilip edilmediğinin görünmesini sağlayan bir özelliktir. Debugging işlemi ancak managed platformlar üzerinde gerçekleştirilebilinir. Managed plaformu şu şekilde tanımlana bilir; yazılan kaynak kodların direkt olarak native koda değil de ortak bir ara dile çevrildiği, ve o ara dilin, başka bir araç tarafından yorumlanarak native koda çevrildiği platformlardır. .Net içerisinde debug kelimesi duyulduğunda akla ilk gelmesi gereken kavram, oluşan IL kodları işletim sistemi için yorumlayan CLR olmalıdır. Çünkü programa debug yeteneğini kazandıran araç CLR’dır. CLR’ın 4 temel işlevi vardır. CIL kodları Native Code’a çevirmek. Bellek yönetimini sağlamak. Thread yönetimini sağlamak. Debugging [25] 43 3. JAVA COLLECTONS FRAMEWORK VE .NET FRAMEWORK bbKARŞILAŞTIRILMASI 3.1. Veri Yapıları Açısından Microsoft C# Programlama Dili ile Sun Micro bbbbSistem Java Programlama Dilinin Karşılaştırılması Her şey objedir (nesnedir) C#’ta bütün sınıflar System.Object’ın alt sınıfıdır. Aynı şekilde javada da bütün sınıflar java.lang.Object’ın alt sınıfıdır. Her iki dilde de bazı Object sınıflar benzerdir. ( ör. System.Object’s ToString(), Java.lang.Object’s toString() ) Sanal makine ve çalışma zamanı dili Java kodları, java byte codelarına derlenirler. Byte code’lar java sanal Makinesinde (JVM) çalıştırılırlar. C# kodları Intermediate Language(IL) ‘de derlenir. Daha sonra Common Language Runtime (CLR)’da çalıştırılır. Her iki platformda Tam Zamanlı derleyiciler aracılığı ile yerel derlemeyi ( compilation) destekler. Heap tabanlı sınıflar ve garbage collection javada nesneler new anahtar kelimesinin kullanılmasıyla heapte oluşturulur. C#’taki sınıfların çoğu new anahtar kelimesinin kullanımı ile heapte yaratılırlar. JVM imha edilecek nesneleri yönetir. Aynı şekilde CLR'de garbage collection algoritması üzerinden imha edilecek nesneleri yönetir. Diziler pürüzlü, dişli (Jagged) Olabilir 44 C ve C++ gibi dillerde, çok boyutlu bir dizinin her dizeni aynı boyutlu olmalıdır. Java ve C# ta diziler aynı olmak zorunda değildir. Çünkü jagged diziler, dizilerin tek boyutlu dizileri olarak yaratılabilir. Bir jagged dizide, diziler bir başka dizinin referansı olabiliyor. İnt [][] myArray = new int[2][]; myArray[0] = new int[3]; myArray[1] = new int[9]; yukarıdaki kodlar hem java hem de C# için geçerlidir. Global metot yok C++’ta olmayan sadece java'daki gibi C#'taki metotlar; üye yada static metot olarak bir sınıfın parçası olmak zorunda. Arayüzlere (İnterfacelere) evet, çoklu kalıtıma, hayır C#, java gibi saf bir soyut sınıfa benzeyen interface kavramını destekler. Benzer şekilde C# ve java ikisi de sadece bir sınıftan kalıtım olabilirler. Fakat ara yüzlerden çoklu kalıtım ya da kılgılanmayı (implementation) alabilirler. Stringler değişmez Bir string nesnesi oluşturulduktan sonra o nesnenin değeri bir daha değişmez. C# System.String sınıfına sahiptir. java da java.lang.String sınıfına sahiptir. Her iki sınıftan da nesneler oluşturulduktan sonra değerleri değişmezler. String metotları kullanıldıklarında var olan string değişmez yeni bir string oluşturulup veri gönderilir. 45 Çizelge 3.1. C# ve java kodu String cssstring = “Gazi Univ.”; String jsstring = “Bilişim”; csString.ToLower(); Jsstring.toLowerCase(); Stringlerde değer değiştirilmez yeni bir kopyası oluşturulur. C#’ta bir stringi object olarak yaratmak için System.Text.StringBuilder classını kullanmak uygun olur. Aynı şekilde java'da da Java.lang.StringBuffer sınıfı kullanılır. Genişletilemeyen (unextendable) sınıflar Hem java da hem de C# ta genişletilemeyen sınıflar mevcuttur. Bunlar base class olamazlar. Bir kalıtım hiyerarşisinde son olacak bir sınıf olmalıdır. Java bu sınıfı başına final getirerek C# ta başına sealed getirerek oluşturuyor. Çizelge 3.2. Genişletilemeyen sınıf örneği C# Kodu Java Kodu Sealed class Ogrenci{ Final class Ogrenci{ string Ad; String Ad; string Soyad; String Soyad; int ID; int ID; Void attend class(){ Void attend Class(){ } } İstisna fırlatma ve yakalama (Throwing ve catching exceptions) İstisnalar C# ve Java'da çoğu benzerliği paylaşırlar. Her ikisi de tyr-catch ve finally bloklarını kullanırlar. Her iki dilde de bir kalıtım hiyerarşisi mevcuttur. Bu da bütün istisnalar Exception classından türetilirler. İstisnalar her iki dilde de yakalanabilir yada fırlatılabilirler her hangi bir hata oluşumu 46 durumunda her iki dilde de kendi istisna sınıflarını oluşturulabilir. İstisna yakalama yada fırlatma temel sınıftan (base classtan) yapılabilir. EK-7'de hem C# hem de Java kod örneği mevcuttur. Tanımlanmış ve static kurucularda üye başlatılması (Member initialization at definition and static constructors) İnstance ve static değişkenler tanımlandıkları C# ve Java'da başlatılabilirler. Eğer değişkenler bir instance değişken ise, o zaman constructor çağırılmadan önce başlanma oluşur. Static üyeler, üyeler ilk kullanımından önce ve instance classın ilk oluşumundan önce başlatılabilirler. Bu da static ve instance üyeleri içeren classlar başlatılmadan önce bir kod bloğunun çalıştırılmasını mümkün kıllar. Bu kod bloklar C#'ta static constructors olarak ve Java'da static initialization bloks olarak adlandırılırlar. Static constructorlar ilk defa yaratılan bir instance klasından önce ve classtaki static metotun çağırılmasından önce çağrılırlar. EK-8'de Tanımlanmış ve static kurucularda üye başlatılması örnek uygulaması mevcuttur. Kutulama (boxing) C# ve java'da değer tiplerini objecte, object tiplerini değer tiplerine çevirmek mümkündür. Buna kutulama (boxing) ve kutudan çıkarma (unboxing) denir. EK-9'de örnek uygulama kodları mevcuttur. Collections Popüler olan dillerin bir çoğu collections framework içermektedir. Collections frameworklerin birinci avantajı ; veri yapıları koleksiyonları üzerinde sıralama yada arama yapmak gerektiğinde gerçek uygulama geliştiricilerini gereksiz kod yazmaktan ve algoritma üretmekten 47 kurtarmasıdır. İkinci bir yararı yeni geliştiricilerin fazla kod yazmadan iki projeyi karşılaştırma olanaklarının olmasıdır. C#, Collections framework System.Collections.Generic sınıflarını namespace’inde System.Collections tutar. ve System.Collections namespace’i interface, abstract sınıfları barındırır. Bunlar abstract veri tiplerini sunarlar; IList, IEnumerable, IDictionary, ICollection ve CollectionBase System.Collections namespace ayrıca ArrayList, Stack, Queue, HashTable ve SortedList gibi bazı somut uygulamalar içermektedir. Somut veri yapılarının tümü tip belirtmedikçe verileri object tipinde barındırırlar. System.Collections.Generic namespace generic(genel) uygulamaya sahip veri yapılarının anahtar kelimesine sahiptir. .bu sınıflar List<T>, Stack<T>, Queue<T>, Dictionary<K,T> ve SortedDictionary<K,T> sınıflarıdır. Java collections framework, java util paketinde çok sayıda sınıf ve interface mevcuttur. Genericler için ayrı bir namespace sahip olmak yerine java.util paketi genericleri de desteklemektedir. JCF’te sets ve jenerik olmayan linkedList gibi C#’ta bulunmayan veri yapıları bulunmaktadır. Ayrıca java collections Frameworkte veri yapılarına ulaşmak için bir den çok metot mevcuttur. Sonuç olarak JCF, veri yapıları arasında en büyüğünü, en küçüğünü bulmak, bir listeyi ters çevirmek , karıştırmak ve sırlamak için çok sayıda algoritmaya sahip. Şuan için, JCF, .NET üzerinden kullanılan C#’tan daha gelişmiştir [27]. Anahtar kelime karmaşıklığı Java ve C# arasında büyük bir syntax benzerliği mevcuttur. 48 4. JAVA KOLEKSİYONLARI C# VE KOLEKSİYONLARI bbbbbPERFORMANSINI KARŞILAŞTIRMA UYGULAMA PROGRAMI 4.1. Programlama Dilleri ve Konseptleri C# ve Java programlama dilleri yorumlanarak çalışan nesne yönelimli programlama dilleridir. Yorumlanmadan önce program kodları, byte kod ve MSIL adı verilen bir ara dile derlenirler. java, oracle'ın bir ürünü olan JVM (java virtiul machine) denilen java sanal makinesi ile çalışır ve onun kütüphanelerini kullanır. C# ise Microsoftun ürünü olan CLR (Common Language Runtime) ile çalışır ve onun kütüphanelerini kullanır. Programlama dillerinde değişik sistem tipleri mevcuttur. C# ve java sistem tipi olarak static tipi kullanır. Ancak 4.0 versiyonundan sonra C# dinamik tip kullanmaya başlamıştır. Bunu da değişkenler üzerinde statik bypass kontrolleri yaparak başarır [7]. Çizelge 4.1. yukarıdaki karakterizasyonları özetliyor. Çizelge 4.1. Programlama dillerinin karakteristik görünümü [7] Uygulama Sistem Ana Stratejleri Java JIT- Tipi Paradigma static OOP compiled C# JIT- Jenerikler Type - erasure static OOP runtime compiled Testler Bu çalışmada performans analizi testleri, koleksiyonlara eleman ekleme işlemi ArrayList, LinkedList, Stack, Hashtable ve HashSet koleksiyonları üzerinde yapılmıştır. Eleman arama, sıralama ve silme işlemi ArrayList, LinkedList, Stack ve HashSet koleksiyonları üzerinden yapılmıştır. Bu koleksiyonların seçilmesinin nedeni bunların hem java, hem de C#'ta kullanılan koleksiyonlar olmasıdır. 49 Testler ekleme işlemi için 100 kez, arama, silme ve sıralama için onar kez gerçekleştirilmiştir. İlk üç sonuçlar dahil edilmemiştir. Sonuç için ortalama değerler kullanılmıştır. Yapılan testlerle her iki programlama dilinin çalışma süreleri, bellek tüketimleri ve yazılan kod uzunlukları incelenmiştir. Test Platformu Aşağıdaki bilgisayar, testler için kullanılmıştır. Windows 8 Single Language Samsung Elektronics Notebook 700 GB Hardisk 8 GB RAM Intel(R) Core(TM) i7- 3630Qm CPU @ 2,4GHz 64bit Sistem Türü Java 7.3.1 , Microsoft Visual Studio 2010 50 4.2. Java ile Java Collections Framework Performans Uygulama Programı Uygulama programı Oracle firmasının Java 7.3.1 programı ve NetBeans IDE ile hazırlanmıştır. Ara yüz programında koleksiyon seçimini sağlayan bir Jlist mevcuttur. İşlem yapılabilmesi için ilk önce koleksiyon seçiminin yapılması gerekmektedir. Birinci kısımda üzerinde işlem yapılması istenen koleksiyonun tür seçimi sağlanmıştır. JCombobox'tan koleksiyona eklenecek eleman sayısı belirlenerek, kullanıcının metin, negatif sayı yada buna benzer hatalı girişleri engellenmiştir. Bunun için Jcombobox listesine 10 'dan 10 000 000'na kadar elemanlar eklenmiştir. Eklenecek elemanların tipinin belirlenmesi için, aynı şekilde Jcombobox listesine int, string, char, double ve nesne tipi elemanlar eklenmiştir. Koleksiyonu oluştur butonuna tıklanarak koleksiyon oluşturulmuştur. Oluşturma esnasında geçen süre mili saniye kullanılan bellek mega bayt cinsinden hesaplanıp label üzerinde kullanıcıyı bilgilendirmiştir. KAYDET butonuna basıldığında veriler JTable üzerine eklenerek gösterilmiştir. Yeni İşlem butonu her şeyi sıfırlamak ve yeni bir koleksiyon oluşturmak için tasarlanmıştır. Tablodaki verilerin Grafikte Göster butanuna tıklanarak grafiği oluşturulması sağlanmıştır. Resim 4.1. Java'da hazırlanan uygulama programı ara yüzü 51 Java uygulama programının birinci kısmında oluşturulacak olan koleksiyonun, koleksiyon çeşidi, eleman sayısı ve eleman tipi seçimi sağlanmıştır. Oluştur butonuna tıklandığında koleksiyonun oluşma süresi ve belek tüketimi hesaplanmıştır. Program, kullanıcı isterse kaydet butonuna tıklayarak koleksiyon çeşidini, eleman sayısını, eleman tipini, oluşma süresini ve bellek tüketimini tabloya kayıt edebilecek, yeni işlem butonu tıklayarak her şeyi sıfırlayabilecek şekilde tasarlanmıştır. Resim 4.2. Java uygulama programı 1.kısım Java uygulama programının ikinci kısmında oluşturulan koleksiyonun oluşma süresini ve bellek tüketimi gösteren label'lar mevcuttur. Elemanları göster butonu, oluşturulan koleksiyonun elemanlarını bir tabloda gösterecek şekilde tasarlanmıştır. Resim 4.3. Java uygulama programı 2. kısım Java uygulama programının üçüncü kısmında oluşturulan koleksiyonun üzerinde işlem yapılmasını sağlayan kontroller vardır. Koleksiyonlar üzerinde eleman ekleme, eleman silme, eleman arama, ve sıralama işlemleri yapılabilmektedir. Hesapla 52 butonuna tıklandığında belirlenen işleme göre geçen süre mili saniye cinsinden hesaplanır, İstendiğinde koleksiyona ait bilgiler tabloya kayıt edilebilmektedir. Resim 4.4. Java uygulama programı 3. kısım 53 4.3. C# ile .Net Collections Framework Koleksiyonları Performans Uygulama bbbbProgramı Uygulama programı Microsoft Visual Studio .NET 2010, visual C# programı ile hazırlanmıştır. Resim 4.5. C#'ta hazırlanan uygulama programı ara yüzü Uygulamanın ara yüz programında Koleksiyon seçimini sağlayan bir listbox mevcuttur. İşlem yapılabilmesi için ilk önce koleksiyon seçiminin yapılması gerekmektedir. Birinci kısımda üzerinde işlem yapılması istenen koleksiyonun tür seçimi sağlanmıştır. Combobox'tan koleksiyona eklenecek eleman sayısı belirlenerek, kullanıcının metin, negatif sayı yada buna benzer hatalı girişleri engellenmiştir. Bunun için combobox listesine 10, 100, 1000, 10000, 10000, 1000000, 10 000 000 seçenekleri barındırılmıştır. . Eklenecek elemanların tipinin belirlenmesi için, aynı şekilde combobox listesine int, string, char, double ve nesne elemanlar eklenmiştir Koleksiyonu oluştur butonuna tıklanarak koleksiyon oluşturulması sağlanmıştır. Oluşturma esnasında geçen süre mili saniye kullanılan bellek mega bayt cinsinden hesaplanıp label üzerinde kullanıcıyı bilgilendirmiştir. KAYDET butonuna basıldığında veriler DataGridView üzerine eklenerek gösterilmiştir. Yeni işlem butonu her şeyi sıfırlamak ve yeni bir koleksiyon 54 oluşturmak için tasarlanmıştır. Tablodaki veriler Grafikte Göster butanuna tıklanarak grafiği oluşturulması sağlanmıştır. Resim 4.6. C# uygulama programı 1. kısım C# uygulama programının ikinci kısmında oluşturulan koleksiyonun oluşma süresini ve bellek tüketimi gösteren label'lar vardır. Elemanları göster butonu oluşturulan koleksiyonun elemanlarını bir tabloda göstermektedir. Resim 4.7. C# uygulama programı 2. kısım Üçüncü kısımda oluşturulan koleksiyonun üzerinde nasıl bir işlem yapılacağı belirlenmektedir. Combobox listesinde eleman ekleme, eleman silme, eleman arama ve elemanları sırala işlemlerini gerçekleştirecek seçenekler bulunmaktadır. Yapılması istenen işlem belirlendikten sonra HESAPLA butonuna tıklanılarak, seçilen işleme göre geçen süre hesaplanmaktadır. İstendiğinde bu veriler kayıt edilebilmekte, bu çalışmada bulunan sonuçlar üzerinden performans karşılaştırmaları analizler ve grafikler oluşturulabilmektedir. 55 Resim 4.8. C# uygulama programı 3. kısım Java uygulama programı ile C# uygulama programın performans karşılaştırmalarının sağlıklı sonuçlar verebilmesi için, uygulama ara yüzleri, kullanılan metotlar, kod satırları, bloglar sabit tutulmaya çalışılmıştır. 56 4.4. Performans Karşılaştırması Programın çalışma hızı, belirlenen bir problemin çözümü için tasarlanan program kodunun görevini yerine getirmesi için gerekli zaman bilgisini veren bir ifadedir; bu bir sayı olabileceği gibi bir matematiksel ifade de olabilmektedir. Bellek gereksinimi ise, programın yürütülmesi sırasında program kodu ve kodun yürütülmesi esnasında kullanılan verilerin işgal ettiği / gereksinim duyduğu toplam bellek alanıdır [29]. Aşağıda Java koleksiyonlarının ve C# koleksiyonlarının eleman ekleme çalışma hızları ve bellek gereksinimleri karşılaştırılmıştır. Bunun yanında koleksiyonlarda eleman sıralama, arama, silme performansları karşılaştırılmıştır. Program kod satırları sabit tutularak performansı etkilemeleri engellenmiştir. Çizelge 4.2. Kullanılan koleksiyon metotlarının zaman karmaşıklığı ArrayList LinkedList Stack HashSet Peek()/get() O(1) O(n) O(1) Add() O(1) O(1) O(1) O(1) Pop()/remove() O(n) O(n) O(1) O(1) Search()/Conrains() O(n) O(n) O(n) O(1) Çizelge 4.3. Kullanılan metotların koleksiyonlarda bulunma durumları Java için ArrayList LinkedList Stack HashSet Sort() Var Var Var Var collection.sort() collection.sort() collection.sort() SortedSet Contains() var var var var Remove() var var var var Sort() var yok yok yok Contains() var var var var Remove() var var yok var C# için 57 4.4.1. Koleksiyonlarda eleman ekleme performans karşılaştırması Çalışma süreleri hesaplanırken şöyle bir yol izlenmiştir: Java ve C# programlarında her koleksiyon için ( Arraylist, LinkedList, Stack, HashTable ve HashSet) integer, string, char, double ve nesne tiplerinde elemanlar eklenmiştir. Her değişken tipinden 100000 ve 1000000 eleman eklenmiştir. Eklenecek elemanlar 0 ile 100 000 000 arasından rastgele sayılar olarak seçilmiştir. Eleman ekleme işlemleri 100'er defa tekrarlanıp ortalamaları alınmıştır. Random nesnesi ile double ve int üretmek mümkündür. Char, string, yada nesne üretilmesi mümkün değildir. Bunun için rastgele üretilen integer değerler koleksiyonlara eklenmesi için string ve char'a dönüştürülmüştür. add( (char)UretilenSayi) add(Integer.toString(UretilenSayi)) HashTable ve HashSet koleksiyonlarına aynı eleman tekrar eklenemediğinden "for" döngüsü ile bu koleksiyonlara eleman eklenmiştir. Performansı etkilememesi için rondom metodu çalıştırılmıştır. Koleksiyonlara eleman eklemek için kullanılan metotlar: UretilenSayi = rnd.nextInt(100000000); Rastgele sayı üretmek için yukarıdaki kod satırı yazılmıştır. Bu kod satırı performansı neredeyse iki kat düşürmüştür. ArrayList koleksiyonuna eleman eklemek için add() metodu kullanılmıştır. Add() metodu hem Java hem de C#'ta koleksiyonun sonuna eleman ekleyerek çalışmaktadır. arraylist.add(UretilenSayi); // integer eleman eklemiştir. arraylist.add(Integer.toString(UretilenSayi)); // String'e çevirip eklemiştir. arraylist.add((char) UretilenSayi); // Char'a çevirip eklemiştir. arraylist.add((double) UretilenSayi); // Double'a çevirip eklemiştir. 58 arraylist.add(newKisi(Integer.toString (UretilenSayi), Integer.toString (UretilenSayi))) nesne tipine çevirip eklemiştir. Tip çevirme işlemi performans kaybına neden olmuştur. Fakat bu işlem bütün koleksiyonlar ve her iki programlama dili için gerçekleştirildiğinden performans analizi açısından bir problem teşkil etmemiştir. LinkedList koleksiyonunda eleman ekleme işlemi hem Java hem de C#'ta en başa yapılarak gerçekleştirilmiştir. linkedlistInt.addFirst(UretilenSayi); Kod satırı koleksiyonun başına integer tipinde eleman ekleyecek şekilde çalıştırılmıştır. String, char, double ve nesne tipindeki elemanların eklenmesi yukarıdaki ArrayList koleksiyonunda olduğu gibi gerçekleştirilmiştir. Sadece add() metodu yerine addFirt() metodu kullanılmıştır. Stack koleksiyonunda eleman ekleme işlemi hem Java hem de C#'ta en başa yapılarak gerçekleştirilmiştir. stackInt.push(UretilenSayi); Kod satırı koleksiyonun başına integer tipinde eleman ekleyecek şekilde çalıştırılmıştır. String, char, double ve nesne tipindeki elemanların eklenmesi yukarıdaki ArrayList koleksiyonunda olduğu gibi gerçekleştirilmiştir. Sadece add() metodu yerine push() metodu kullanılmıştır. HashTable koleksiyonuna eleman ekleme işlemi diğer koleksiyonlardan farklılık göstermiştir. HashTable sınıfı elemanları anahtar ve değer olarak almıştır. Bu sınıf anahtarları değerlere göndererek bir Hashtable ambarı yaratmıştır. Null olmayan her nesne anahtar yada değer olarak kullanılmıştır [11]. Koleksiyona eleman ekleme Hash fonksiyonuna göre gerçekleştirilmiştir. Hash fonksiyonu, bir anahtar (key) kullanarak tablo üzerinden bir pozisyon (index) üretmiştir. Verilerin tablodaki yerlerini hash fonksiyonu belirlemiştir. Hash kodun üretilmesi performans kaybına neden olmuştur. 59 for (int j = 0; j < elemansayisi; j++) { hashtable.put(j, j); // Java da integer tipinde eleman ekleme kod satırı hashtable.Add(j, j); // C#'ta integer tipinde eleman ekleme kod satırı String, char, double ve nesne tipindeki elemanların eklenmesi yukarıdaki ArrayList koleksiyonunda olduğu gibi gerçekleştirilmiştir. Sadece Java'da add() metodu yerine put() metodu kullanılmıştır. HashSet koleksiyonuna eleman ekleme işlemi hem Java hem de C#'ta en sona yapılarak gerçekleştirilmiştir. for (int j = 0; j < elemansayisi; j++) { hashsetInt.add(j); Kod satırı koleksiyonun sonuna integer tipinde eleman ekleyecek şekilde çalıştırılmıştır. String, char, double ve nesne tipindeki elemanların eklenmesi yukarıdaki ArrayList koleksiyonunda olduğu gibi gerçekleştirilmiştir. 60 4.4.1.1. Çalışma süreleri açısından karşılaştırma Java programlama dilinde koleksiyonlara eleman eklenince geçen süreyi hesaplatabilmek için System.currentTimeMillis(); metodu kullanılmıştır [28]. Bu metot, koleksiyona eleman eklenmeden hemen önce ve eklendikten hemen sonra çalıştırılmıştır. Bulunan değerler değişkenlere atanmıştır. Zamanlar arasındaki fark geçen süreyi vermiştir. Bu şekilde geçen süre mili saniye cinsinden hesaplanmıştır. Koleksiyonlara nesne eklemek için, aşağıda kodu verilmiş bir Kisi sınıfı oluşturulmuştur. public class Kisi { String a,b; Kisi(String ad,String soyad){ a=ad;b=soyad; }} Çizelge 4.4. Java programında koleksiyonlara eleman eklenince geçe süre (ms) Eleman Eleman sayısı tipi 100000 integer string char double nesne 1000000 integer string char double nesne Arraylist 1,55 5,14 1,65 1,85 9,17 15,67 49,24 13,36 13,12 87,01 Linkedlist 2,32 5,21 1,84 2,29 9,08 18,14 52,71 17,26 18,03 96,11 Stack 4,45 5,84 3,52 4,14 9,77 33,29 63,54 32,13 36,84 104,95 HashTable 5,47 10,02 3,67 4,23 24,94 41,65 117,21 33 35,53 591,09 HashSet 5,02 6,15 2,43 3,89 14,83 24,3 74,23 21,68 32,83 161 61 Java Koleksiyonları Geçen Süre Geçen Süre mili saniye 700 600 500 400 Arraylist 300 Linkedlist 200 Stack 100 HashTable 100000 nesne double char string integer nesne double char string HashSet integer 0 1000000 Şekil 4.1. Java koleksiyonlarına eleman eklenince geçen ortalama süre Şekil 4.1. incelendiğinde: nesne tipinde eleman eklemek en maliyetlisi olarak belirlenmiştir. Koleksiyonlar kendi aralarında incelendiğinde Arraylist koleksiyonu en performanslısı olarak belirlenmiştir. Arkasından Stack, Linkedlist, HashSet ve HashTable gelmiştir. Bunu belirleyen koleksiyonların eleman ekleme algoritmaları ve zaman karmaşıklığıdır. ArrayList koleksiyona eleman ekleme işlemini index numarasına göre dizi mantığı ile gerçekleştirmiştir. Bu da onun performansını olumlu yönde etkilemiştir. Stack ve LinkedList, koleksiyona eleman ekleme işlemini en başa yaparak gerçekleştirmiştir. HashSet koleksiyonu eleman ekleme işlemini ekleme sırasına göre gerçekleştirmemiştir. HashTable koleksiyonu ise elemanları ekleyebilmek için bir hash kod üretmiştir. Hash fonksiyonu ile oluşturulan bu kod elemanın yerini belirlemiştir. Buda performans kaybına neden olmuştur. C# programlama dilinde, ArrayList koleksiyonuna eleman eklenince geçen süreyi hesaplamak için DateTime.Now() metodu ve TimeSpan sınıfının bir nesnesi kullanılmıştır. 62 Koleksiyonlara nesne eklemek için, aşağıda kodu verilmiş bir Kisi sınıfı oluşturulmuştur. class Kisi { string isim { get; set; } string soyisim { get; set; } public Kisi(string ad, string soyad) { isim = ad; soyisim = soyad;}} C# koleksiyonlarına eleman eklenince Çizelge 4.5.'teki sonuçlar elde edilmiştir. Çizelge 4.5. C# Programlama Dili için geçen süre Eleman Eleman sayısı tipi 100000 integer string char double nesne 1000000 integer string char double nesne Arraylist 2,88 15,06 3 4,83 35,25 73,58 222,53 52,85 74,85 545,56 Linkedlist 3,65 16,95 3,47 5,65 49 120,09 358,01 141,77 162,57 666 Stack 2,98 15,85 2,94 4,95 38,55 75,07 235,19 60,97 86,56 555,4 HashTable HashSet 5,4 3,18 32,74 15,59 3,92 10,32 6,2 115,27 37,87 168,95 30,72 797,27 254,4 35,81 346,94 59,17 1966,74 673,95 63 C# Koleksiyonları Geçen Süre Geçen süre mili saniye 2500 2000 1500 Arraylist 1000 Linkedlist Stack 500 HashTable 100000 nesne double char string integer nesne double char string integer 0 HashSet 1000000 Şekil 4.2. C# koleksiyonlarına eleman eklenince geçen ortalama süre Yukarıdaki grafik şekli incelendiğinde; C# koleksiyonlarında en iyi performansı ArrayList koleksiyonu oluşturmuştur. En kötü performansı HashTable koleksiyonu göstermiştir. Java programlama dilinde olduğu gibi nesne tipinde eleman eklendiğinde en kötü performans sergilenmiştir. HashTable koleksiyonuna aynı veri tekrar eklendiğinde hata ile karşılaştırılmıştır. Hashtable koleksiyonuna char tipinde veri eklenmemiştir. HashSet'te aynı veriyi eklememiştir fakat hata da vermemiştir. 64 1000 100 Arraylist Linkedlist 10 Stack HashTable 100000 1000000 java 2 100000 nesne double char string integer nesne double char string integer nesne double char string integer nesne char double string integer 1 HashSet 1000000 c# Şekil 4.3. Java ve C# koleksiyonlarına eleman ekleyince geçen süre karşılaştırması Şekil 4.3. incelendiğinde Java'daki koleksiyonların C#'taki koleksiyonlara göre eleman ekleme işlemini daha kısa bir sürede gerçekleştirdiği görülmüştür. Performansı etkileyen yapıların başında JVM ve CLR sanal makineleri olmuştur. Diğer etkenler koleksiyonların yapıları, yazılan kod satırları ve metotlar olmuştur. 65 4.4.1.2 Kullanılan bellek açısından karşılaştırma Kullanılan bellek hesaplanırken, çalışma süreleri hesaplanmasındaki yol izlenmiştir: ArrayList, LinkedList, Stack, HashSet ve HashTable koleksiyonlarına integer, string, char, double nesne tiplerinde 100000 ve 1000000 sayılarında elemanlar eklenmiştir. Program kodları 100'er defa çalıştırılıp ortalamaları alınmıştır.Bu şekilde kullanılan bellek değeri hesaplanmıştır. Java programında Koleksiyonlara eleman eklenince kullanılan belleği hesaplatmak için Runtime sınıfından bir runtime nesnesi yaratılmıştır [28]. Koleksiyona eleman eklemeye başlamadan önce runtime.gc() metodu çağrılarak garbage collector çalıştırılmıştır. 100000 ve 1000000 sayılarında elemanlar eklendikten sonra long memory = runtime.totalMemory() - runtime.freeMemory(); kod satırlarıyla toplam bellekten kalan bellek çıkarılmıştır. Bu şekilde kullanılan bellek hesaplanmıştır. Bulunan sonuç byte türündendir. Bu sonucu Mbyte'a çevirmek için aşağıdaki kod satırları yazılmıştır; private static final long MEGABYTE = 1024L * 1024L public static long bytesToMegabytes(long bytes) { return bytes / MEGABYTE } Aynı kod satırları diğer koleksiyonlar için ve diğer değişken tipleri için tekrarlanmıştır. Bulunan sonuçlar Çizelge 4.6.'da gösterilmiştir. 66 Çizelge 4.6. Java programlama dili için kullanılan bellek Eleman Eleman sayısı tipi Arraylist Linkedlist 100000 integer 2 5 string 6 8,08 char 2 5,12 double 3 4 nesne 13,13 15 1000000 integer 15 39 string 54 77 char 15 39 double 24,09 46,67 nesne 132 156 Stack 2 5,1 2 2 13 17 53,99 17 24 132,99 HashTable HashSet 6,02 5 14 9 5 4 9 6 29 16 61,91 46 140 85 33 18 77 54 292 161 Java Koleksiyonları Kullanılan Bellek 350 Bellek Mb 300 250 200 Arraylist 150 Linkedlist 100 Stack 50 HashTable 100000 nesne double char string integer nesne double char string integer 0 HashSet 1000000 Şekil 4.4. Java koleksiyonlarına eleman eklenince kullanılan bellek Şekil 4.4. Java koleksiyonlarına eleman eklenince kullanılan bellek karşılaştırmasını vermiştir. Koleksiyonlara nesne tipinde elemanlar eklendiğinde çok büyük bir farkla bellek tüketilmiştir. En az bellek tüketimi integer ve char tipi eleman eklendiğinde görülmüştür. Koleksiyonlara baktığımızda; En az bellek tüketimini ArrayList ve Stack koleksiyonu gerçekleştirirken, en çok bellek tüketimini HashTable koleksiyonu gerçekleştirmiştir. 67 C# programında kullanılan belleği hesaplatmak için GC.GetTotalMemory(false) metodu çalıştırılmıştır. Bu metodu çalıştırmadan önce GC.Collect() metodu çalıştırılarak çöp toplayıcısının devreye girmesi sağlanmıştır. Bu sayede boş yere kullanılan bellek serbest bırakılmıştır. Kullanılan kod satırları diğer koleksiyonlar için ve diğer değişken tipleri için tekrarlanmıştır. Bulunan sonuçlar Çizelge 4.7.'de gösterilmiştir. Çizelge 4.7. C# programlama dili için kullanılan bellek Eleman Eleman sayısı tipi 100000 integer string char double nesne 1000000 integer string char double nesne Arraylist 1 3 1 2 7 11,08 30 11 15 75,14 Linkedlist 3 6 3 2 10 23 53 23 28,76 98 Stack 1 3 1 2 7 12 30 12 15 75,1 HashTable HashSet 3 0,04 5 2 0,02 3 0,08 12 6 23,03 0,32 53 26 0,04 30 0,66 136,31 73,26 160 140 120 100 80 60 40 20 0 Arraylist Linkedlist Stack 100000 nesne double char string integer nesne double char string HashTable integer Bellek Mb C# Koleksiyonları Kullanılan Bellek HashSet 1000000 Şekil 4.5. C# koleksiyonlarına eleman eklenince kullanılan bellek 68 Çizelge 4.5. incelendiğinde bellek tüketimi açısından en maliyetlisi HashTable koleksiyonu ve koleksiyonlara nesne tipinde eleman eklenince gerçekleşmiştir. HashSet koleksiyonuna char tipinde eleman eklenince istenilen sayıda eleman eklenememiştir fakat program hata da vermemiştir. Bu yüzden char tipinde eleman ekleme işleminde az bellek tüketimi gerçekleşmiştir. String tipinde eleman ekleme işleminin diğer değer tiplerine göre daha maliyetli olmasının bir nedeni tip çevirme işleminin gerçekleştirilmiş olmasıdır. Koleksiyonlar değerlendirildiğinde en az bellek tüketimi HashSet koleksiyonunda gerçekleşmiştir. 350 300 Mega Byte 250 200 Arraylist 150 Linkedlist 100 Stack 50 HashTable 0 100000 1000000 Java integer string char double nesne integer string char double nesne integer string char double nesne integer string char double nesne HashSet 100000 1000000 C# Şekil 4.6. Java ve C# koleksiyonlarına eleman eklenince kullanılan bellek karşılaştırması Yukarıdaki 4.6. grafik şekli incelendiğinde Koleksiyonlara eleman eklenince geçen süre bazında java daha performanslı iken kullanılan bellek açısından C# çok daha hesaplıdır. Eklenen eleman sayısı artırıldığında Java daha az bellek tüketiyormuş gibi görünse de grafiğe bir bütün olarak bakıldığında C#'ın daha az bellek tükettiği fark edilmektedir. 69 Şekil 4.7. C# ve java programlama dillerinin kullandığı süre ve bellek kullanımları bbbbbbbbbilişkisini gösteren regresyon eğrisi Şekilde görüldüğü gibi süreyle birlikte belli bir bellek kullanımı söz konusu. Yalnız eklenen eleman sayısı sabit tutulduğunda, ekleme süresi artsa bile kullanılan bellek sabit kalma eğilimi göstermektedir. Jeremy Singer 2003 yılında JVM'nin CLR'ye karşı yaptığı performans araştırmasında iki sanal makinenin performans açısından çok fazla bir farklılığın olmadığı sonucuna varmıştır [30]. 2011 yılında Pratibha Singh ve arkadaşları JVM ve CLR üzerinde yaptığı araştırmalar sonucunda JVM'nin CLR'ye göre daha çok bellek tükettiği sonucuna varmıştır [31]. 70 4.4.2. Koleksiyonlarda sıralama performans karşılaştırması Karşılaştırma 1000000 integer elemanlı ArrayList, LinkedList, Stack ve HashSet koleksiyonları arasında gerçekleştirilmiştir. Koleksiyonları oluşturan elemanlar random nesnesi ile üretilen 0 ile 100 000 000 sayı arasından eklenmiştir. Sıralama işleminin ilk üç denemesi sayılmayıp 10'ar defa tekrarlanmıştır. Bulunan sonuçların ortalamaları alınmıştır. Java'da List arayüzünü uygulayan AraryList, LinkedList ve Stack koleksiyonlarının sıralanması için Collections sınıfının static sort() metodu kullanılmıştır. Collections.sort(arraylist); Collections.sort(linkedlist); Collections.sort(stack); HashSet koleksiyonu Set ara yüzünü uygular. HashSet koleksiyonunun elemanlarının sıralanması için ; Set sortedset = new TreeSet(hashset); kod satırları yazılmıştır. C#'ta LinkedList, Stack ve HashSet koleksiyonlarında Sort() metodu bulunmadığından bu koleksiyonları sıralamak için koleksiyon elemanları bir diziye aktarılmıştır. Kod satırları aşağıda verilmiştir. Array arr = new stack.ToArray(); Array.Sort(arr); Elemanların sıralanması için arr dizisi sıralanmıştır. Aslında burada sıralanan LinkedList, Stack ve HashSet koleksiyonları değil arr dizisi olmuştur. Performans karşılaştırması açısından sağlıklı bir sonuç vermeyeceğinden bu koleksiyonlar için elde edilen veriler grafiğe eklenmemiştir. 71 Çizelge 4.8. Java ve C# koleksiyonların sıralama performansları Program java c# Eleman sayısı İşlem Arraylist 1000000 Sıralama 296 1000000 Sıralama 618 Linkedlist 341 Stack 385 HashSet 551 1000000 int Elemanlı Koleksiyonların Sıralanması 700 Geçen Süre Ms 600 500 400 Arraylist 300 Linkedlist 200 Stack 100 HashSet 0 Sıralama Sıralama 1000000 1000000 java c# Şekil 4.8. Java ve C# koleksiyonlarının sıralama performansları Java koleksiyonlarında en iyi performansı ArrayList koleksiyonu göstermiştir. ArrayList koleksiyonu elemanlarını dizi mantığı ile tutar. En kötü performansı HashSet koleksiyonu göstermiştir. HashSet koleksiyonu elemanları ekleme sırasına göre değil oluşturduğu bir hash koda göre tutar. 72 4.4.3. Koleksiyonlarda arama performans karşılaştırması Arama işlemi 10 000 000 integer elemanlı ArrayList, LinkedList, Stack ve HashSet koleksiyonları arasında gerçekleştirilmiştir. Arama işlemi için Contains() metodu kullanılmıştır. Koleksiyonları oluşturan elemanlar random nesnesi ile üretilen 0 ile 100 000 000 sayı arasından eklenmiştir. Arama işleminin ilk üç denemesi sayılmayıp uygulama 10 defa tekrarlandıktan sonra bulunan sonuçların ortalamaları alınmıştır. Arama işleminde iki durum söz konusu olmuştur. İlki eleman bulununca diğeri eleman bulunmayınca. Her iki durum için de karşılaştırmalar yapılmıştır. LinkedList koleksiyonunda aranan eleman en başta olunca eleman 0 ms'de bulunmuştur. HashSet koleksiyonunda eleman bulunsa da bulunmasa da geçen süre 0 ms olarak hesaplanmıştır. HashSet koleksiyonu elemanlarına oluşturduğu hash kodu ile direk ulaştığından elemanlarına ulaşması sabit sürede olup zaman karmaşıklı O(1) olarak bulunmuştur. C#'ın Stack koleksiyonunda eleman araması sonucunda eleman mevcut ise geçen süre 0 ms olarak hesaplanmıştır. Eleman koleksiyon içersinde mevcut değilse geçen süre çizelge 4.9'da verilmiştir. Çizelge 4.9. Java ve C# koleksiyonların arama performansları Program java c# Eleman saysı İşlem 10000000 Arama bulundu Arama bulunamadı 10000000 Arama bulundu Arama bulunamadı Arraylist Linkedlist Stack HashSet 56 43,5 17,7 0 63,3 76,5 97,4 43,8 18,1 0 0 0 76,5 43,8 160,5 0 73 Geçen Süre ms 1000000 int Elemanlı Koleksiyonların Aranması 180 160 140 120 100 80 60 40 20 0 Arraylist Linkedlist Stack Arama Arama bulundu bulunamadı Arama Arama bulundu bulunamadı 10000000 10000000 java c# HashSet Şekil 4.9. Java ve C# koleksiyonlarının arama performansları Şekil 4.9. incelendiğinde programlama dillerinde elemanın bulunup bulunmaması performansta pek bir değişiklik göstermemiştir. Aranan eleman bütün uygulamalarda en son eleman için gerçekleştirilmiştir. En baştaki eleman için işlem yapıldığında neredeyse 0 ms'de işlem yapılmıştır. En büyük performans farkı C# programında Stack koleksiyonunda gözlemlenmiştir. Var olan eleman 0 ms'de bulunurken olmayan eleman yaklaşık 160 ms'de bulunmuştur. 74 4.4.4. Koleksiyonlarda silme performans karşılaştırması Silme işlemi 10 000 000 integer elemanlı ArrayList, LinkedList, Stack ve HashSet koleksiyonları arasında gerçekleştirilmiştir. Silme işlemi için Remove() metodu kullanılmıştır. Koleksiyonları oluşturan elemanlar random nesnesi ile üretilen 0 ile 100 000 000 sayı arasından eklenmiştir. Arama işleminin ilk üç denemesi sayılmayıp uygulama 10 defa tekrarlandıktan sonra bulunan sonuçların ortalamaları alınmıştır. C# koleksiyonları arasından Stack koleksiyonunda Remove() metodu olmadığından silme işlemi için Pop() metodu kullanılmıştır. Sağlıklı sonuçların elde edilebilmesi için Stack koleksiyonunda silme işlemi için geçen süre karşılaştırmaya dahil edilmemiştir. Çizelge 4.10. Java ve C# koleksiyonların silme performansları Eleman sayısı Program java c# İşlem 1000000 Silme 1000000 Silme Arraylist 23,5 59,1 Linkedlist 107,2 31,2 Stack 17 - HashSet 0 0 1000000 int Elemanlı Koleksiyonların Silinmesi Geçen Süre ms 120 100 80 60 Arraylist 40 Linkedlist Stack 20 HashSet 0 Silme Silme 1000000 1000000 java c# Şekil 4.10. Java ve C# koleksiyonlarının silme performansları 75 Silme ve arama işlemlerinde aranan yada silinen elemanın en sonda olmasına dikkat edilmiştir. Bu saye de oluşacak en kötü ihtimal bulunmuştur. HashSet koleksiyonu her iki programlama dili için de en iyi performansı göstermiştir. Aranan yada silinen elemanın konumuna bakılmaksızın işlemi 0 ms'de gerçekleştirmiştir. Java programlama dilinde LinkedList koleksiyonu en kötü performansı göstermiştir. C#'ta ise en kötü performansı ArrayList koleksiyonu göstermiştir. Çizelge 4.11. Java ve C# koleksiyonlarının süre bazında karşılaştırılması Program java c# Eleman Sayısı İşlem 1000000 Sıralama 1000000 Eleman ekleme 10000000 Arama bulundu Arama 10000000 bulunamadı 10000000 Silme 1000000 Sıralama 1000000 Eleman ekleme 10000000 Arama bulundu Arama 10000000 bulunamadı 10000000 Silme Çizelge 4.11. Java ve C# Arraylist 296 15,67 56 Linkedlist 341 18,14 43,5 Stack 385 33,29 17,7 HashSet 551 24,03 0 63,3 23,5 97,4 107,2 18,1 17 0 0 618 73,58 76,5 yok 120,09 43,8 yok 75,07 0 Yok 30,72 0 76,5 59,1 43,8 31,2 160,5 yok 0 0 koleksiyonlarında integer tipinde elemanlar üzerinde yapılan eleman arama, sıralama, ekleme ve silme işlemlerini göstermiştir. 76 5. SONUÇ Java koleksiyonları (Arraylist, LinkedList, Stack, HashSet) kendi aralarında karşılaştırıldığında, çalışma süresi açısından en maliyetlisinin LinkedList koleksiyonu olduğu görünmüştür. HashSet koleksiyonu sıralama algoritmasında kötü bir performans göstermiş olsa da genel olarak bakıldığında hem tükettiği bellek açısından hem de geçen süre bakımından iyi bir performans sergilemiştir. C# koleksiyonları (Arraylist, LinkedList, Stack, HashTable) kendi aralarında karşılaştırıldığında, yine en iyi performansı HashSet koleksiyonu sergilemiştir. Koleksiyona eleman eklerken ArrayList iyi bir performans sergilerken arama ve silme uygulamalarında HashSet'ten sonra LinkedList koleksiyonu iyi bir performans sergilemiştir. C# koleksiyonlarına bir bütün olarak bakıldığında geçen süre açısından ArrayList en kötü performansı göstermiştir. Kullanılan bellek açısından bakıldığında en maliyetlisinin LinkedList koleksiyonu olduğu görülmüştür. Java ve C# koleksiyonları karşılaştırıldığında, koleksiyonlara eleman eklerken geçen ortalama süre C#'ta daha fazla olduğu görülmüştür. C#'taki Arraylist koleksiyonu Java'daki Arraylist koleksiyonundan yaklaşık olarak 5 kat daha uzun bir sürede ekleme işlemi yaparken, LinkedList koleksiyonunda bu 6 kat, Stack koleksiyonunda 2 kat daha uzun bir sürede gerçekleştirdiği görülmüştür. Koleksiyonlara eleman eklenirken kullanılan bellek açısından koleksiyonlar incelendiğinde durum tersine dönmüştür. C# koleksiyonlarına eleman eklenirken kullanılan belleğin Java'daki koleksiyonlardan daha az bellek tükettiği görülmüştür. C# koleksiyonları java koleksiyonlarından bellek tüketimi açısından daha avantajlı olduğu sonucuna varılmıştır. Her iki programlama dilinin koleksiyonlarına bakıldığında arama, silme ve ekleme işlemlerinde en uygun koleksiyon seçiminin HashSet olduğu görülmüştür. 77 Java ve C# programlama dillerine baktığımızda yaptığımız deneyler bize şu sonucu göstermektedir; C# koleksiyonlara eleman eklerken daha uzun sürede yapsa bile kullandığı bellek daha azdır. Geçen ortalama süre Java'da daha iyi iken kullanılan bellek açısından C# daha iyidir. C# ve java programlama dillerinin kullandığı süre ve bellek kullanımları ilişkisini gösteren regresyon eğrisine baktığımızda, süreyle birlikte belli bir bellek kullanımı söz konusudur. Yalnız eklenen eleman sayısı sabit tutulduğunda, ekleme süresi artsa bile kullanılan bellek sabit kalma eğilimi göstermektedir. 78 KAYNAKLAR 1. İnternet: Sun Microsystems "Java Programming Language World Wide Web Site" http://java.sun.com (2013). 2. Algan, S., "Her Yönüyle C# 4.0", Pusula, İstanbul, 20-32 (2011). 3. Şahin, M., "Java, python ve ruby dillerinin performans karşılaştırması", Akademik Bilişim, 1-5 (2007). 4. Wentworth, S., Langan, D., Hain, T. F., "An empirical analysis of the java collections framework versus the c++ standard template library," 1st Annual ACM Southeast Conference Savannah, Georgia, March 7–8 ( 2003). 5. Prechelt L., “An empirical comparison of seven programming languages”, Computer, 33, 10, 23 –29, ISSN 0018-9162, doi:10.1109/2.876288 (2000). 6. Cesarini F., Pappalardo, V. and Santoro, C., "A comparative evaluation of imperative and functional implementations of the imap protocol", 7th ACMSIGPLAN workshop on ERLANG ’08, ACM, New York, NY, USA, ISBN 978-1-60558-065-4, 29–40, doi:10.1145/1411273.1411279 (2008). 7. Geyer-Schulz, A., Stein, M., "A comparison of five programming languages in a graph clustering scenario", Journal of Universal Computer Science, vol. 19, no. 3 (2013) 8. Collins, W. J., "Data Structures And The Java Collections Framework", McGrawHill, USA (2005). 9. Flanagan, D., "Java collection framework, in java™ in a nutshell." O'Relly, Avustralya, p. chapter 23 (1999). 10. Schildt, H., "Java SE 6", 1st ed., Selçuk Tüzel, Ed. İstanbul, Turkey: Alfa 459-531 (2007). 11. Karaçay, T., "Java Veri Yapıları (Collection Framework)", Pusula, İstanbul 1-606 (2011). 12. İnternet: MSDN ".Net Framework 4.5" http://msdn.microsoft.com/enus/library/ hh425099(v=vs.110).aspx (2013). 13. Internet: ".Net Framework: http://www.codeguru.com (2011). Collections And Generics" 79 14. Internet: " Basics of .NET Collections in C# " http://www.codeproject.com/Articles/31640/Basics-of-NET-Collections-in-C (2008) 15. İnternet: Oracle "Java Tutorial," http://docs.oracle.com/javase/tutorial/ (2013) 16. İnternet: Oracle, “Uses of Interface java.util.Collection” http://docs.oracle.com/javase/7/docs/api/java/util/classuse/Collection.html#java.util (2013). 17. Algan, S., " C# İle Asp.net ", Pusula, İstanbul, 1-13 (2011). 18. İnternet: ".Net Mimarisine kulubu.com/makale/ (2013). Genel Bakış" http://www.bilisim- 19. İnternet: "Java Jre, Jvm, Jdk Nedir?" http://karahanmehmet.com/index.php?show=detail&article=38 (2012). 20. İnternet: "JVM (Java Virtual Machine) Nedir? http//www.kurumsaljava.com/2012/12/jvm-java-virtual-machine/ (2012). 21. İnternet: Vikipedi, "Java http://tr.wikipedia.org/wiki/Sanal_makine (2013). Sanal " Makinesi" 22. İnternet:bbbbb“The Java Virtual http://www.artima.com/insidejvm/ed2/jvm.html (2011). Machine” 23. İnternet: ".Net Mimarisi ve Çalışma Yapısı" http://onursalkaya.blogspot.com/2011/02/net-mimarisi-ve-calsma-yaps.html (2011). 24. İnternet: ".Net Mimarisi’ne http://www.yazilimakademi.com/ (2012). Gene Bir Bakış" 25. İnternet: Blog "C# Clr, Cls, Msıl Nedir?" http://safakunel.blogspot.com/2010/07/c-clr-cls-msil-nedir.html (2010). 26. İnternet: Microsoft “Common Language Runtime Clr" http://msdn.microsoft.com/en-us/library/8bs2ecf4(v=vs.110).aspx ( 2013). 27. İnternet: Blog, "A Comparison Of Microsoft's C# Programming Language To Sun Microsystems' Java Programming Language" http://www.25hoursaday.com/CsharpVsJava.html ( 2013). 80 28. Çölkesen, R., "Veri Yapıları ve Algoritmalar", Papatya, İstanbul 135-424 (2007). 29. İnternet: Blog "Java Performance - Memory And Runtime Analysis Tutorial" http://www.vogella.com (2013). 30. Singer, J., " JVM versus CLR: A Comparative Study", University of Cambridge Computer Laboratory, Cambridge, CB3 0FD, UK, 1-3, (2003). 31. Singh, P., Sharma, D., Agrawal, S., "By Performance Metrics Analysis of CLR & JVM– A Survey ", International Journal of Computer Trends and Technology, 1-4 , July to Aug Issue (2011). 81 EKLER 82 EKLER EK-1. Java collections sınıfının önemli metotları public class Collections { // No Constructor // Public Constants public static final java.util.List EMPTY_LIST ; public static final Map EMPTY_MAP ; public static final Set EMPTY_SET ; // Public Class Methods public static int binarySearch (java.util.List list, Object key); public static int binarySearch (java.util.List list, Object key, Comparator c); public static void copy (java.util.List dest, java.util.List src); public static Enumeration enumeration (Collection c); public static void fill (java.util.List list, Object o); public static Object max (Collection coll); public static Object max (Collection coll, Comparator comp); public static Object min (Collection coll); public static Object min (Collection coll, Comparator comp); public static java.util.List nCopies (int n, Object o); public static void reverse (java.util.List l); public static Comparator reverseOrder (); public static void shuffle (java.util.List list); public static void shuffle (java.util.List list, Random rnd); public static Set singleton (Object o); public static java.util.List singletonList (Object o); public static Map singletonMap (Object key, Object value); public static void sort (java.util.List list); 83 EK-1 (Devam) Java collections sınıfının önemli metotları public static void sort (java.util.List list, Comparator c); public static Collection synchronizedCollection (Collection c); public static java.util.List synchronizedList (java.util.List list); public static Map synchronizedMap (Map m); public static Set synchronizedSet (Set s); public static SortedMap synchronizedSortedMap (SortedMap m); public static SortedSet synchronizedSortedSet (SortedSet s); public static Collection unmodifiableCollection (Collection c); public static java.util.List unmodifiableList (java.util.List list); public static Map unmodifiableMap (Map m); public static Set unmodifiableSet (Set s); public static SortedMap unmodifiableSortedMap (SortedMap m); public static SortedSet unmodifiableSortedSet (SortedSet s); } [2] 84 EK-2. System.Object sınıfının metotları, özellikleri ve örnek uygulamaları Statik Metod object.Equals(object objA, object objB) Bu metot true yada false döndürür. Eğer objA ile objB’nin referansları aynı yada null değerleri varsa true döndürür. Aksi taktirde false döndürür. Örnek 1. int n1 = 2; int n2 = 3; bool result1 = object.Equals(n1, n2); // false döndürür. çünkü n1 & n2 değer tipi // ve bir değer tipiyle karşılatırılmalı. string s1 = "test"; string s2 = "test"; bool result2 = object.Equals(s1, s2); //true döndürür. s1 & s2 //referans tipidir. Fakat Equals(object obj)metodu string sınıfından türeyen bir nesne sınıfının metodudur. Peki neden true döndürüyor Çünkü s1 ve s2 değerleri ile karşılatırılıyorlar. object obj1 = new Person(1, "Test1"); object obj2 = new Person(1, "Test1"); bool result3 = object.Equals(obj1, obj2); // false döndürür. obj1 ve obj2 reference tipidir. Metot Equals(object obj) İki string değeri karşılaştırır. Örnek 2. string s1 = "Test"; string s2 = "Test"; bool result1 = s1.Equals(s2); // true döndürür. Çünkü s1 & s2 aynı değere sahip. 85 EK-2 (Devam) System.Object sınıfının metotları, özellikleri ve örnek uygulamaları object obj1 = new Person(1, "Test1"); object obj2 = new Person(1, "Test1"); object obj3 = obj1; bool result2 = obj1.Equals(obj2); // false döndürür. // Çünkü obj1 & obj2 farklı nesneler. bool result3 = obj1.Equals(obj3); // true döndürür. Çünkü obj1 & obj3 aynı nesneler. GetHashCode() Geçerli nesnenin HashCode’nu verir. Türeyen sınıf tarafından overide edilir. Örnek 3. object obj1 = 4; object obj2 = "Test"; object obj3 = new Person(1, "Test1"); int result1 = obj1.GetHashCode(); // 4 döndürür. int result2 = obj2.GetHashCode(); // -354185577 döndürür. int result3 = obj3.GetHashCode(); // 2418355 döndürür. GetType() Geçerli değerin tipini verir. Örnek 4. object obj1 = 4; object obj2 = "Test"; object obj3 = new Person(1, "Test1"); string type1 = obj1.GetType().ToString(); // System.Int32 döndürür string type2 = obj2.GetType().ToString(); // System.String döndürür. string type3 = obj3.GetType().ToString(); // DotNetCollections döndürür. // CollectionExp.Person. 86 EK-2 (Devam) System.Object sınıfının metotları, özellikleri ve örnek uygulamaları ToString() Değerleri string tipine çevirir. Örnek 5. object obj1 = 4; object obj2 = "Test"; object obj3 = new Person(1, "Test1"); string s1 = obj1.ToString(); // 4 döndürür. string s2 = obj2.ToString(); // Test döndürür. string s3 = obj3.ToString(); // DotNetCollections döndürür 87 EK-3. System.Collections.IEnumerable arayüzünün metotları, özellikleri ve örnek bbbbbbuygulamaları [4]. Methods GetEnumerator() Örnek 6. Array array = new int[] { 12, 24, 26, 35, 40, 59 }; IEnumerator iEnum = array.GetEnumerator(); string msg = ""; while (iEnum.MoveNext()) { int n = (int)iEnum.Current; msg += n.ToString() + "\n"; } MessageBox.Show(msg); 88 EK-4. System.Collections.ICollection arayüzünün metotları, özellikleri ve örnek bbbbbbuygulamaları [4]. Özellikler Count Eleman sayısını döndürür. Örnek 7. // Array List ArrayList sourceList = new ArrayList(); sourceList.Add(10); sourceList.Add(20); sourceList.Add(30); int count = sourceList.Count; // count = 3. IsSynchronized Erişilen ICollection senkronize edilmişse true döndürür. SyncRoot Bir nesne döndürür. Örnek 8. ArrayList sourceList = new ArrayList(); sourceList.Add(10); sourceList.Add(20); sourceList.Add(30); lock (sourceList.SyncRoot) { string list = string.Empty; foreach (object value in sourceList) { if (list.Length > 0) 89 EK-4 (Devam) System.Collections.ICollection arayüzünün metotları, özellikleri ve bbbbbörnek uygulamaları [4]. list += ", "; list += value.ToString(); } MessageBox.Show(list); } Methods CopyTo(Array array, int index) Örnek 9. // int tipindeki diziyi başka bir int tipindeki diziye kopyalar int[] sourceIDs = new int[] { 1, 2, 3, 4, 5 }; int[] destinationIDs = new int[sourceIDs.Length]; sourceIDs.CopyTo(destinationIDs, 0); // destinationIDs = 1, 2, 3, 4, 5 ArrayList sourceList = new ArrayList(); sourceList.Add(10); sourceList.Add(20); sourceList.Add(30); int[] destinationList = new int[5]; destinationList[0] = 1; destinationList[1] = 5; sourceList.CopyTo(destinationList, 2); // 2. Indexten balayıp kopyalar. 90 EK-5. System.Collections.IList arayüzünün metotları, özellikleri ve bbbbbbbuygulamaları [4] Özellikler IsFixedSize Eğer sabit bir boyuta sahipse true döndürür. Örnek 10. ArrayList arrayList = new ArrayList(); bool isFixedSize = arrayList.IsFixedSize; // false, Çünkü ArrayList // sabit boyutlu değil IsReadOnly Sadece okunabilirse true döndürür. Örnek 11. ArrayList arrayList = new ArrayList(); arrayList.Add(1); arrayList.Add(2); arrayList.Add(3); bool readOnly = arrayList.IsReadOnly; // false, çünkü default array // list sadece okunabilir değil // var olan listeden sadece okunailir bir liste oluşturuluyor. ArrayList readOnlyList = ArrayList.ReadOnly(arrayList); bool isNewListReadOnly = readOnlyList.IsReadOnly; // true kullanıcı bunu // değiştiremez. Methods Add(object value) Iliste eleman ekler Örnek 12. ArrayList arrayList = new ArrayList(); arrayList.Add(1); // 1. Elemanı ekler. örnek 91 EK-5 (Devam) System.Collections.IList arayüzünün metotları, özellikleri ve örnek bbbbbbuygulamaları [4] arrayList.Add(2); // 2. Elemanı ekler. arrayList.Add(3); // 3. Elemanı ekler. Clear() Ilisten bütün elemanları siler. Örnek 13. ArrayList arrayList = new ArrayList(); arrayList.Add(1); arrayList.Add(2); arrayList.Add(3); int itemsCount = arrayList.Count; // 3 arrayList.Clear(); itemsCount = arrayList.Count; // 0 Contains(object value) Ilistin herhangi bir elemana sahip olup olmadığını bulur sahipse true değilse false döndürür. Örnek 14. ArrayList arrayList = new ArrayList(); arrayList.Add(new Person(1,"test")); Person person1 = new Person(1, "test"); Person person2 = new Person(2, "test2"); bool result1 = arrayList.Contains(person1); // true bool result2 = arrayList.Contains(person2); // false IndexOf(object value) Ilist‘teki elemanın index numarasını verir. Bu metot ayrıca Equals ve CompareTo metotlarını kullanır. Örnek 15. ArrayList arrayList = new ArrayList(); 92 EK-5 (Devam) System.Collections.IList arayüzünün metotları, özellikleri ve örnek bbbbbuygulamaları [4] arrayList.Add(new Person(1, "test1")); arrayList.Add(new Person(2, "test2")); arrayList.Add(new Person(3, "test3")); // yeni nesne yarat Person person3 = new Person(3, "test3"); Person person4 = new Person(4, "test4"); int result1 = arrayList.IndexOf(person3); // 2, int result2 = arrayList.IndexOf(person4); // -1. Çünkü listede yok Insert(int index, object value) Iliste belirli index numarası ile eleman ekleyen metottur. Ilist boş ise yada eleman sayısından büyük bir index numarası ile araya eleman eklemek istenirse ArgumentOutOfRangeException hatayı fırlatır. Aynı şekilde sadece okunabilir yada sabit boyutlu bir Iliste eleman eklendiğinde NotSupportedException hatası fırlatılır. Örnek 16. ArrayList arrayList = new ArrayList(); arrayList.Add(new Person(1, "test1")); arrayList.Add(new Person(2, "test2")); arrayList.Add(new Person(3, "test3")); // yeni bir nesne yaratılıyor Person person =new Person(4, "test4"); // elemanı 2. Indexe sıkıtır arrayList.Insert(2, person); Remove(object value) Ilisten eleman silmeye yarayan metottur. Örnek 17. ArrayList arrayList = new ArrayList(); arrayList.Add(new Person(1, "test1")); 93 EK-6. System.Collections.IDictionary arayüzünün metotları, özellikleri ve örnek uygulamaları [4]. arrayList.Add(new Person(2, "test2")); arrayList.Add(new Person(3, "test3")); arrayList.RemoveAt(1); IDictionary koleksiyonları anahtar değer ikilisi olarak sunar. Özellikler IsFixedSize Eğer IDictionary nesnesi sabit boyutlu ise true döndürür. Örnek 18. Hashtable hashList = new Hashtable(); hashList.Add(1, "item#1"); hashList.Add(2, "item#2"); hashList.Add(3, "item#3"); bool result = hashList.IsFixedSize; // false IsReadOnly Eğer IDictionary nesnesi salt okunur ise true döndürür. Örnek 19. Hashtable hashList = new Hashtable(); hashList.Add(1, "item#1"); hashList.Add(2, "item#2"); hashList.Add(3, "item#3"); bool result = hashList.IsReadOnly; Keys IDictionary nesne anahtarları içeren ıcollection nesnesini döndürür. Örnek 20. 94 EK-6 (Devam) System.Collections.IDictionary arayüzünün metotları, özellikleri ve örnek uygulamaları [4]. Hashtable hashList = new Hashtable(); hashList.Add(1, "item#1"); hashList.Add(2, "item#2"); hashList.Add(3, "item#3"); ICollection keys = hashList.Keys; string[] strKeys = new string[keys.Count]; int index =0; foreach (int key in keys) { strKeys[index++] = key.ToString(); } string keysList = string.Join(", ",strKeys); // 3, 2, 1 Values IDictionary nesne değerini içeren ıcollection nesnesini döndürür. Örnek 21. Hashtable hashList = new Hashtable(); hashList.Add(1, "item#1"); hashList.Add(2, "item#2"); hashList.Add(3, "item#3"); ICollection values = hashList.Values; string[] strValues = new string[values.Count]; int index = 0; foreach (string value in values) { strValues[index++] = value; } string valueList = string.Join(", ", strValues); //item#1, item#2, item#3 Methods 95 EK-6 (Devam) System.Collections.IDictionary arayüzünün metotları, özellikleri ve örnek uygulamaları [4]. Add(object key, object value) I Dictionary belirli bir değer ve anahtara sahip eleman ekler. Örnek 22. Hashtable hashList = new Hashtable(); hashList.Add(1, "item#1"); hashList.Add(2, "item#2"); hashList.Add(3, "item#3"); Clear() IDictionary nesnesinden bütün elemanları siler. Örnek 23. Hashtable hashList = new Hashtable(); hashList.Add(1, "item#1"); hashList.Add(2, "item#2"); hashList.Add(3, "item#3"); hashList.Clear(); // it removes all item from the list. Contains(object key) Eğer IDictionary nesnesinde belirli anahtardaki bir eleman varsa true döndürür. Örnek 24. Hashtable hashList = new Hashtable(); hashList.Add(1, "item#1"); hashList.Add(2, "item#2"); hashList.Add(3, "item#3"); bool result = hashList.Contains(1); // true GetEnumerator() 96 EK-6 (Devam) System.Collections.IDictionary arayüzünün metotları, özellikleri ve bbbbbörnek uygulamaları [4]. IDictionary nesnesi için bir IDictionaryEnumerator nesnesi üretir. Örnek 25. Hashtable hashList = new Hashtable(); hashList.Add(1, "item#1"); hashList.Add(2, "item#2"); hashList.Add(3, "item#3"); IDictionaryEnumerator dicEnum = hashList.GetEnumerator(); string items = string.Empty; while (dicEnum.MoveNext()) { items += string.Format("{0} : {1}\n", dicEnum.Key, dicEnum.Value); } MessageBox.Show(items); Remove(object key) IDictionary nesnesinden belirli anahtara sahip nesneyi siler. Örnek 26. Hashtable hashList = new Hashtable(); hashList.Add(1, "item#1"); hashList.Add(2, "item#2"); hashList.Add(3, "item#3"); hashList.Remove(2); // anahtar numarası 2 olan nesneyi siler[4]. 97 EK-7. C# ve java programlama dillerinde uygulama kodları throw exception C# codu using System; using System.IO; class MyException: Exception{ public MyException(string message): base(message){ } public MyException(string message, Exception innerException): base(message, innerException){ } } public class ExceptionTest { static void DoStuff(){ throw new FileNotFoundException(); } public static void Main(string[] args){ try{ try{ DoStuff(); return; //won't get to execute }catch(IOException ioe){ /* parent of FileNotFoundException */ throw new MyException("MyException occured", ioe); /* rethrow new exception with inner exception specified */ } }finally{ Console.WriteLine("***Finally block executes even though MyException not caught***"); } }//Main(string[]) } // ExceptionTest 98 EK-7 (Devam) C# ve java programlama dillerinde uygulama kodları throw exception Java kodu class MyException extends Exception{ public MyException(String message){ super(message); } public MyException(String message, Exception innerException){ super(message, innerException); } } public class ExceptionTest { static void doStuff(){ throw new ArithmeticException(); } public static void main(String[] args) throws Exception{ try{ try{ doStuff(); return; //won't get to execute }catch(RuntimeException re){ /* parent of ArithmeticException */ throw new MyException("MyException occured", re); /* rethrow new exception with cause specified */ } }finally{ System.out.println("***Finally block executes even though MyException not caught***"); } }//main(string[]) } // ExceptionTest 99 EK-8. Tanımlanmış ve static kurucularda üye başlatılması C# ve Java kodu using System; class StaticInitTest{ string instMember = InitInstance(); string staMember = InitStatic(); StaticInitTest(){ Console.WriteLine("In instance constructor"); } static StaticInitTest(){ Console.WriteLine("In static constructor"); } static String InitInstance(){ Console.WriteLine("Initializing instance variable"); return "instance"; } static String InitStatic(){ Console.WriteLine("Initializing static variable"); return "static"; } static void DoStuff(){ Console.WriteLine("Invoking static DoStuff() method"); } public static void Main(string[] args){ Console.WriteLine("Beginning main()"); StaticInitTest.DoStuff(); StaticInitTest sti = new StaticInitTest(); Console.WriteLine("Completed main()"); } } 100 EK-8 (Devam) Tanımlanmış ve static kurucularda üye başlatılması C# ve Java kodu Tanımlanmış ve static kurucularda üye başlatılması Java kodu class StaticInitTest{ String instMember = initInstance(); String staMember = initStatic(); StaticInitTest(){ System.out.println("In instance constructor"); } static{ System.out.println("In static constructor"); } static String initInstance(){ System.out.println("Initializing instance variable"); return "instance"; } static String initStatic(){ System.out.println("Initializing static variable"); return "static"; } static void doStuff(){ System.out.println("Invoking static DoStuff() method"); } public static void main(String[] args){ System.out.println("Beginning main()"); StaticInitTest.doStuff(); StaticInitTest sti = new StaticInitTest(); System.out.println("Completed main()"); }} Her iki örneğin Çıktısı: In static constructor 101 EK-8 (Devam) Tanımlanmış ve static kurucularda üye başlatılması C# ve Java kodu Beginning main() Invoking static DoStuff() method Initializing instance variable Initializing static variable In instance constructor 999pleted main() 102 EK-9. Boxing ve Unboxing boxing ve unboxing C# kodu using System; using System.Collections; //stack allocated structs also need to be boxed to be treated as objects struct Point{ //member fields private int x; private int y; public Point (int x, int y){ this.x = x; this.y = y; } public override string ToString(){ return String.Format("({0}, {1})", x, y); } }//Point class Test{ public static void PrintString(object o){ Console.WriteLine(o); } public static void Main(string[] args){ Point p = new Point(10, 15); ArrayList list = new ArrayList(); int z = 100; PrintString(p); //p boxed to object when passed to PrintString PrintString(z); //z boxed to object when passed to PrintString // integers and float boxed when stored in collection // therefore no need for Java-like wrapper classes list.Add(1); 103 EK- 9 (Devam) Boxing ve Unboxing list.Add(13.12); list.Add(z); for(int i =0; i < list.Count; i++) PrintString(list[i]); } } boxing ve unboxing Java kodu import java.util.*; class Test{ public static void PrintString(Object o){ System.out.println(o); } public static void PrintInt(int i){ System.out.println(i); } public static void main(String[] args){ Vector list = new Vector(); int z = 100; Integer x = new Integer(300); EK-2 (Devam) C# ve java programlama dillerinde uygulama kodları PrintString(z); //z boxed to object when passed to PrintString PrintInt(x); //x unboxed to int when passed to PrintInt // integers and float boxed when stored in collection // therefore no need for Java wrapper classes list.add(1); list.add(13.12); 104 list.add(z); for(int i =0; i < list.size(); i++) PrintString(list.elementAt(i)); } 105 ÖZGEÇMİŞ Kişisel Bilgiler Soyadı, adı : EBREN KARA, Şükran Uyruğu : T.C. Doğum tarihi ve yeri : 10.06.1984 Cizre Medeni hali : Evli e-mail : sukran.ebren@gazi.edu.tr Eğitim Derece Birimi Mezuniyet Tarihi Lisans Mersin Üniversitesi 2007 Lise Şırnak Anadolu Lisesi 2002 Yıl Yer Görev 2007 - 2009 Milli Eğitim Bakanlığı Bilgisayar Öğretmenliği 2008 - 2009 Şırnak Üniversitesi Öğretim Görevlisi 2009 - Hakkari Üniversitesi Öğretim Görevlisi İş Deneyimi Yabancı Dil İngilizce Hobiler Kitap Okumak, Ailem ile zaman geçirmek, müzik dinlemek