Java Günlüğüm
Yazılım, Java, BT, azıcık felsefe, biraz mizah...
  • Udemy Eğitimleri
  • Temiz Kod
  • Tasarım Kalıpları
  • Hakkımda
  • Arşiv
RSS
22 Aralık 2014

Bir Algoritma Bağlamında Güzellik ve Performans – I

Akin Bilgisayar Bilimleri, Java monte carlo, performans, pi

Monte Carlo metodu, algoritmik çözümü zor olan matematiksel ve fiziksel problemleri, rastgele (random) sayılar üreterek, simule ederek çözmeyi amaçlayan yaklaşımlara verilen ortak addır. Monte Carlo’daki gazinolardaki kumar aletlerinin rastgele sonuç üretmesine atıf olarak bu isim verilmiştir. Optimizasyon problemlerinde sıklıkla kullanılır.

Monte Carlo metodunu, pi sayısını bulmak için de kullanabiliriz. Bakın şöyle: Kartezyen koordinat sisteminde merkezi (0,0) noktasında olan ve yarı çapı 1 birim olan bir çember çizin ile bu çembere teğet geçen bir de kare çizin. Çemberin ve karenin alanlarının oranı pi/4 yapar. Bu şu demektir: Bu çizime rastgele bir nokta atarsanız, bu noktanın, çemberin içine düşmesi ihtimali pi/4 eder.

Bu gerçeği tersten okuyalım şimdi de: Eğer bu çizime sonsuz tane nokta atılırsa, bu şekli tamamen kapsamış oluruz. Yani bu şekile n tane nokta atalım ve bu noktaların r tanesinin çemberin içine düştüğünü varsayalım. n sonsuza giderken, 4r/n oranının pi‘ye yaklaştığını görürsünüz. n‘yi 1 yaparsanız, yani 1 nokta atarsanız bu oran ya 0 ya da 4 olacaktır. n sayısını arttırdıkça bu oranın gittikçe pi sayısına yakınsadığını, ne kadar çok nokta atarsanız, pi‘nin gerçek değerine (ki böyle bir şey yok! dolayısıyla daha doğru tabirle, virgülden sonraki rakamları doğru bir şekilde bulmaya başlarsınız) yakınsarsınız. Bu durumu şuradaki ya da şuradaki applet ile görebilirsiniz ya da Youtube’taki pek çok videodan birini seyredebilirsiniz.

Bu algoritmayı Java ile şöyle gerçekleştirebiliriz:

import java.util.Scanner;

public class MonteCarloPI {
	public static void main(String[] args) {
		int dotsInCircle = 0;
		System.out.print("Number of points: ");
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		
		double start = System.currentTimeMillis();
		for(int i = 0; i<n; i++){
			double x = Math.random();
			double y = Math.random();
//			double distance = Math.sqrt(Math.pow(x, 2) + Math.pow(y,2));
			double distance = x*x + y*y;
			if(distance <= 1.0)
				dotsInCircle++;
		}
		double finish = System.currentTimeMillis();
		
		double seconds = (finish-start)/1000;
		double myPI = (double) 4*dotsInCircle/n;
		System.out.println("My PI is: " + myPI + " and Java's PI is: " + Math.PI);
		System.out.println("Time is: " + seconds);
	}
}

Yukarıdaki program, girilen sayı kadar rasgele (x, y) noktası üreterek, her bir noktanın (0, 0) merkez noktasına uzaklığı hesaplanır ve bu uzaklığın 1’e eşit ya da ondan küçük olup olmadığı kontrol edilir, eğer eşit ya da küçük ise, bu demektir ki nokta çemberin içine düşmüştür ve yukarıdaki algoritmanın anlatımında r dediğimiz ve programda dotsInCircle ile temsil ettiğimiz değişkenin değeri arttırılır.

Yukarıdaki kodu n=1 için çalıştırırsanız sonuç ya 0 ya da 4 çıkacaktır. Çünkü o tek nokta ya dairenin içine ya da dışına düşecektir. Dolayısıyla salınım 0 ile 4 arasında gerçekleşecektir. Ama örneğin n=10 yaparsanız gelebilecek sonuçlardan birisi şöyle olabilir: Hesaplanan pi = 2.800000  ve hata yüzdesi %10.873232. Yani yaklaşık %11 hatayla Java’nın Math sınıfındaki PI’ye (3.141592653589793) yakınsanmış demektir. Ama n sayısını 1.000.000.000 yapınca pi = 3.141536  ve hata yüzdesi % 0.001809 olarak elde ettim.

Tabi sağlıklı ortalama değerler için, aynı n sayısı için olarak olabildiğince çok çalıştırma yapılmalıdır. Ben de bu amaçla yukarıdaki algoritmayı aşağıdaki gibi değiştirdim.

package org.javaturk.oop.ch05;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class MonteCarloPITiming {
	private static int runCount = 100;
	private static int n;
	
	private static List<Double> pis = new ArrayList<Double>();
	private static List<Double> times = new ArrayList<Double>();
	private static List<Double> percentages = new ArrayList<Double>();
	
	public static void main(String[] args) {
		System.out.print("Number of points: ");
		Scanner in = new Scanner(System.in);
		n = in.nextInt();
		for(int i = 0; i < runCount; i++){
			calculatePI();
		}
		printResults();
	}

	private static void printResults() {
		double meanTime = 0;
		double meanError = 0;
		System.out.printf("%10s %10s %10s\n", "Time  ", "Calculated PI", "Error %  ");
		for(int i = 0; i < runCount; i++){
			meanTime += times.get(i).doubleValue();
			meanError += percentages.get(i).doubleValue();
			System.out.printf("%10f %10f %10f\n", times.get(i).doubleValue(), pis.get(i).doubleValue(), percentages.get(i).doubleValue());
		}
		meanTime /= runCount;
		meanError /= runCount;
		System.out.printf("Mean time: %10f\n", meanTime);
		System.out.printf("Mean error: %10f", meanError);
	}

	public static void calculatePI() {
		int dotsInCircle = 0;
		double start = System.currentTimeMillis();
		for (int i = 0; i < n; i++) {
			double x = Math.random();
			double y = Math.random();
			// double distance = Math.sqrt(Math.pow(x, 2) + Math.pow(y,2));
			double distance = x * x + y * y;
			if (distance <= 1.0)
				dotsInCircle++;
		}
		double finish = System.currentTimeMillis();
		double seconds = (finish - start);
		times.add(seconds);
		double myPI = (double) 4 * dotsInCircle / n;
		pis.add(myPI);
		double diff = Math.abs((Math.PI - myPI)); 
		double percentage = diff * 100 / Math.PI;
		percentages.add(percentage);
	}

}

Yani programın başındaki runCount (ki değeri 100) kadar aynı n sayısı için algoritmayı çalıştırıyorum ve her çalışmanın sonuçlarını List nesnelerine koyuyorum. runCount defa çalışma bitince de hem sürenin hem de hata yüzdesinin ortalamasını alıyorum. Beklentim şu: n arttıkça süre de artacak çünkü daha çok nokta atacağım ama tabi olarak hata yüzdesi azalacak çünkü pi‘ye daha çok yakınsayacağım. Örneğin farklı n sayıları için aşağıdaki ortalama ölçümleri elde ettim:

MacBook Pro i7 2,5 GHz. 16 GB RAM, MacOS 10.10.1 Yosemite konfigürasyonunda:

n Süre (ms) Error (%)
10 0,20 16,02
100 0,30 2,683942
1.000 0,40 1,423435
10.000 1,10 0,505523
100.000 4,90 0,104983
1.000.000 41.70 0,041766
10.000.000 415,90 0,011628
100.000.000 4097,10 0,002976
1.000.000.000 41001,00 0,00116

Toshiba Satellite i7 2,4 GHz. 8 GB RAM, Windows 8.1 konfigürasyonunda:

n Süre (ms) Error (%)
10 0 15,278875
100 0 5,337467
1.000 0 1,097579
10.000 1,6 0,3616
100.000 6,2 0,086118
1.000.000 48,5 0,037688
10.000.000 465,7 0,011813
100.000.000 4646,8 0,003846
1.000.000.000 45751 0,000768

Her iki konfigürasyonda da Java 1.8.0_25 HotSpot 64-bit server JVM çalışıyordu.

Yukarıdaki sonuçlardan şunları söyleyebiliriz:

  • Algoritmada n tane for döngüsünün her birinde iki defa Math.random() çağrısı, iki defa çarpma işlemi, bir tane kıyas (<=), bir tane de artım yapılıyor. Dolayısıyla algoritmanın karmaşıklığı 0(n) (bigO(n)) görünüyor. Yani algoritmanın zaman ihtiyacı doğrusal olarak artacaktır. Zaten sonuçlar da bunu gösteriyor. n sayısı 10 katına çıkınca, gerekli süre de yaklaşık 10 katına çıkıyor.
  • İkincisi konfigürasyonları çok yakın, JVMleri aynı sürüm olmasına rağmen MacBook Pro, Toshiba’dan yaklaşık %10 civarında daha hızlı çalıştı. Bu durum MacBookPro’daki CPU’nun biraz daha hızlı olması yanında envai çeşit farklı faktörler üzerinden açıklanabilir. Çok önemli bir fark değil açıkçası.

Bu algoritma o kadar basit ki, anlaşılması, kodlanması vs. çok kolay. Ama bu algoritma bir o kadar da güzel, güzel ötesi, neffiiisss. Matematiğin ve sayıların güzelliğini ortaya koyuyor, herkesin anlayacağı basitlikte.

Toplam görüntülenme sayısı: 1161

9 Bunu beğendim 🙂
Tweet
Follow me
Tweet to @kaldiroglu
04 Aralık 2014

Deneyimin Yok Ama!

Akin BT

Bir genç arkadaşımın, “okuldan tanıdığım, sağlam çocuktur, iş arıyor” deyip bana CVsini gönderdiği emaili ülkemizin BT piyasasında hatırı sayılır işler yapan insan kaynakları  şirketine sahip bir tanıdığıma gönderdim. O da bana “deneyimi yok ama olsun sağol :)” diye cevap yazdı. Bu arkadaşımla zaman zaman buluşup konuşuruz, ortak bir şeyler yapalım vs. diye, dolayısıyla kendisini iyi tanıyorum. Bu “deneyimi yok ama” kısmı aslen onun düşüncesi değil, burası, tamamen arkadaşımın iş yaptığı ve daima “tecrübeli” aday arayan insanların yani BT yöneticilerinin zihin yapısını ifade ediyor.

Evet malesef öyle bir ülkede yaşıyoruz ki, kimse yeni öğrenene tahammül edemiyor. Diğer sektörlerde de öyle mi bilmiyorum ama en azından BT ve futbol sektörümüzde durum bu. “Biz tecrübeli programcı arıyoruz!” Zannedersin uzaya füze fırlatan rampa sisteminin yazılımını yazacak! Ya da CMMI-5 seviyesinde bir yazılım şirketinde ya da BT biriminde yönetici, o yüzden bu kaliteye ayak uyduracak yazılımcı arıyor. Sorsan “nedir tecrübeli?” diye sadece yıl cinsinden bir tarif yapabilir: “işte, 5 sene falan Java ile uğraşmış olsun”. Aslında bunu diyen, “5 sene ile Java ile uğraşmış olma”nın daha detayda ne anlama geldiği hakkında emin olun bir cümle daha söylemekte zorlanacaktır, hatta söylediklerinin 5 senelik Java tecrübesiyle alakası olmadığını anlayarsınız. Şunun gibi: “yani CVS’le falan uğraşmış olsun”!

Bütün bunları ben, bu sektörde iş ararken hiç yaşamadım. Çünkü juinor programmer olarak iş ararken ABD’deydim ve orada gerek önüme konan sınavlardan gerek ise benimle yapılan iş görüşmelerinden, benimle ilgilenen kişilerin tam da benim gibi, bilgisi olan ama tecrübesi olmayan kişiler aradıklarını rahatlıkla anlayabiliyordum. Çünkü pozisyon, bekletiler vs. hakkında konuşurken benimle görüşen kişiler, örneğin “2 senedir bizimle olan ve başından bu yana projede bulunan, … tecrübeli bir arkadaş var, onunla çalışacaksın” diye sağlam bir alt yapıya sahip olup da tecrübesi olmayan kişiye uygun bir konumlandırma yapabiliyorlardı. Bu ülkede ise herkesin “Alex” olması bekleniyor. “Ama tecrüben yok!” Eeee, sen iş vermezsen, stajyer olarak gelene de “aman gölge etme dersen”, insanlar nasıl tecrübe sahibi olacaklar ki? Sanırım bu yüzden sadece 22 yaşında olup henüz üniversiteden mezun olmamış bir gencin bana gönderdiği CVsinde “6 yıl tecrübe” yazıyordu! Bir insan MIT ya da Stanford’dan doktora bile alsa, tecrübesi “0”dır. Ama işte böyle yaparak, BT sektörüne girmek isteyenleri de bu şekilde saçma davranışlara sürüklüyoruz. Sonuçta iki yanlış bir doğru etmiyor.

Zaten size bir şey söyliyeyim mi? Tecrübeden kastedilen ise gerçekte sadece “hızlı iş çıkarmak”tır. Kimse, “bizim projemizde performans çok önemli, o yüzden yazılacak kodun kalitesi kritik, ancak tecrübeliler yazabilir bunu” diye düşünmüyor. İşin komik yanı zaten bu: Tecrübe bu ulkede sadece yıl ile ölçülüyor, kişinin gerçekten ne yaptığıyla değil. Mesela ben 2001’de ABD’den dönüp te bu ülkenin en büyük krizini geçirdiği günlerde iş ararken iki kişi hariç hiç kimse benimle CVmin üzerinden geçip, ABD’de ne yaptığımı sorgulamadı. Kimse hangi projelerde, hangi rollerle yer aldın, neler yaptın, sorumlulukların neydi vb. sorulara girmedi. Herkes, ABD’den gelmişliğimle ve yaşımın  30’u geçmişliğiyle ilgilendi. Ben teknik pozisyonlara başvurdum ama insanlar beni kendi yöneticileriyle kıyasladılar. Sadece iki kişi CVmdekiler üzerinen tek tek gitti, detayını öğrendi. İlki, zaten yabancı bir şirketin IT müdürü olan ABDli bir adamdı, diğeri de ABD’de 18 sene kalıp, bu ülkeye dönmüş ve BT işi kurmuş Türk bir patrondu.

Bir diğer konu da aslında her projede her türlü tecrübeye sahip kişilere ihtiyaç olacağı gerçeğidir. Bu durum hem tecrübe, hem de yetenek vb. pek çok açıdan geçerlidir. Yani tutun 10 tane Alex bulup Fener’e koyun mesela. Fener, Bayern’mi olacak? Her projede diğerlerine yol gösterecek tecrübe, zeka ve özgüvende insanlar kadar, onlardan sayıca daha fazla olan ama daha az tecrübeli ve bilgili çalışanlara da ihtiyaç vardır. Savaşı sadece generallerden kurulu bir orduyla kazanamazsınız ki! Bana her tecrübeli 1 yazılımcının yanına yarı tercübede 2-3 kişi koyacak şekilde bir proje verin, hiç bir tecrübe zaafiyeti yaşamadan, projenin büyüklüğüne göre muhtemelen pek çok yeni mezun ile projeyi yapabilirim. Yeni mezunları seçerken ince eler sık dokurum o ayrı. Sertifikası olana daha olumlu bakarım örneğin. Biz bir binayı yaparken herkesin tecrübeli inşaat mühendisi olmasını bekliyor muyuz? Neden o zaman bir yazılım projesinde herkesin mühendis ve tecrübeli olmasını bekliyoruz ki? Herkesin tecrübeli yazılımcı olduğu yerde pek çok ufak-tefek, basit ve tekdüze iş, çok pahalı çalışanlar tarafından yapılıyor demektir. Açıkçası yönetimden anlamadığımız için, hasbel kader yöneticilere sahip olduğumuz için, tecrübesizleri çalıştıracak yetkinliğe sahip değiliz. Tecrübeli olan zaten iyi çalışır, tecrübesiz ise iyi çalışmayı öğrenmeye ihtiyacı vardır, dolayısıyla yönetilmeye, yol gösterilmeye, yetiştirilmeye ihtiyacı vardır. Tecrübesizi işe almayarak kendi tembelliğimizi gösteriyoruz bence.

Zeki, yetenekli ve iyi eğitimli az sayıda insan ile, orta seviye zeka ve yeteneğe sahip insanlarla, karmaşık işler bile ne kadar basit, öngörülebilir hale getirilir görmek isterseniz, ABD’yi bir ziyaret edin ederim. Bakın o “aptal” dediğimiz insanlar, bizim zekilerimizin bu topraklarda yapamadığını ne kadar basit bir şekilde yapıyorlar.

Bir diğer nokta da yeni mezunların ortama bir enerji ve canlılık getirdikleri gerçeğidir. Yeni mezunların, ortamları daha neşeli kıldıkları, daha yaratıcı çözümler bulduklarını çok defa gözlemlemişimdir. Nasıl hep aynı tipten insanların buludukları yerler tekdüze oluyorsa, sadece tecrübelilerin yanına koyacağınız tecrübesizlerle bu tekdüzeliği aşabilir, taze kan ve enerji alabilirsiniz. Örneğin ben, azimli, motivasyonunu kaybetmemiş 2-3 sene tecrübeli kişilerle harmanlanmış, iyi seçilmiş yeni mezunların, düzgün bir yönetim ile uzun vadede, 10 küsur senelik tecrübeli, ama bu kültür içinde motivasyonunu kaybetmiş kişilerden oluşmuş bir takımdan daha çok ve kaliteli iş çıkarabileceğime inanıyorum.

Her şey gibi insan da her yaşında ögretilmeye, eğitilmeye ve yol gösterilmeye muhtaçtır. Herkes, bilmediğinin, yaşamadığının tecrübesizidir. İyi yöneticiler de, işlerinin gerektirdiği yetkinlikleri ve seviyelerini iyi bilen ve takımlarını buna göre bir uyum içerisinde kurabilen ve onları motive eden kişilerdir. Bizim sektörümüzde “yıl”a indirgenmiş tecrübe ve yetkinlikten dolayı çok enerji ve insan kaybediyoruz.

 

Toplam görüntülenme sayısı: 4437

54 Bunu beğendim 🙂
Tweet
Follow me
Tweet to @kaldiroglu
29 Kasım 2014

Java’ya Nasıl Başlarım? Java’yı Nasıl Öğrenirim?

Akin Java, Java Dersleri Java Öğren, Java öğreniyorum, Java öğrenmek

Burada üç-beş yazıdan oluşan bir “Java’ya Nasıl Başlarım? Java’yı Nasıl Öğrenirim?” dizisine başlamıştım. Bu dizi halen de bitmiş değil ama var olan yazıları burada listelemem sanırım faydalı olacak:

  • Java’ya Nasıl Başlarım? Java’yı Nasıl Öğrenirim? – I
  • Java’ya Nasıl Başlarım? Java’yı Nasıl Öğrenirim? – II
  • Java’ya Nasıl Başlarım? Java’yı Nasıl Öğrenirim? – III
  • Java’ya Nasıl Başlarım? Java’yı Nasıl Öğrenirim? – IV
  • Java’ya Nasıl Başlarım? Java’yı Nasıl Öğrenirim? – V

Ayrıca aşağıdakı yazılar da yakından konuyla ilgilidir:

  • Java SE’den Sonra Ne Öğrenelim? İş Arayanlara Öneriler
  • Oracle’ın Java sertifikaları üzerine yazılar
  • Java Kitapları Üzerinde – İngilizce Kaynaklar

Toplam görüntülenme sayısı: 10265

45 Bunu beğendim 🙂
Tweet
Follow me
Tweet to @kaldiroglu
25 Kasım 2014

Yazılımların Performansı ve Performans İyileştirme

Akin Java performans

Java’nın performansı ile ilgili olarak daha önce bu yazıyı yayınlamıştım. Şimdi bu konuda biraz daha temel tanımlar ve metot üzerinden ilerleyelim. Sonrasında Java’ya özel performans konularını ele alırız.

Aslında performans derken birden fazla şeyi kastederiz, dolayısıyla performans kelimesi aslında “hız” etrafında kümelenmiş pek çok farklı kalite kriterinin şemsiye ismidir. Bakın o şemsiye altında neler olabilir:

  • Son kullanıcı cevap zamanı (responsiveness): Son kullanıcının sistemi kullanırken yaptığı hareketlere yönelik sistemin cevap verme zamanıdır. Son kullanıcıyı en fazla ilgilendiren ve uzun olduğunda canını sıkan ve çalışma ritmini bozan faktördür. “Sistem yavaş” dendiğinde çoğu zaman bu kastedilir ama çok farklı sebepleri olabilir. Performans iyileştirme çalışmalarının en öncelikli hedefi, son kullanıcı cevap zamanını makul seviyelere indirmek ve ortalama olarak kabul edilebilir bir son kullanıcı performans sağlamaktır.
  • Ölçeklenirlik (scalability): Uygulamanın davranışının artan yük altında nasıl değiştiğini ifade eder. Ölçeklenirliği en temelde etkileyen iki faktör, artan canlı kullanıcı sayısı ve büyüyen veri miktarıdır. Ölçeklenirliği kötü olan sistemlerin son kullanıcı cevap zamanı da kötüdür. Ama bu durum her zaman ortaya çıkmaz, bazen belli zamanlarda daha fazla görünür olur. Bu durum tamamen sistem yükünün devamlı değişir yapıda olmasından kaynaklanır. Performans iyileştirme çalışmalarında ölçeklenirlik, son kullanıcı cevap zamanını makul sınırlarda tutacak şekilde, ikinci öncelik olarak ele alınır.
  • Bellek kullanımı (memory footprint): Uygulamanın bellek kullanımıdır. Genelde bellek kaçağı (memory leak) olarak ortaya çıkar ve kurumsal uygulamaların ölçeklenirliğini en fazla etkileyen faktördür. Bellek kaçakları, Java ile geliştirilmiş uygulamalarda çöp toplama (garbage collection) mekanizmasının sık ve uzun sürelerle devreye girmesine sebep olduğundan ve bu faaliyet ciddi kaynak tükettiğinden, nihayetinde son kullanıcı cevap zamanını menfi yönde etkiler. Bellek kullanımı iyileştirilmediği taktirde, nihayetinde ölçeklenirliği tamamen ortadan kaldırır ve sistemleri, sıklıkla tekrar başlatılması gerekli hale getirir. Performans iyileştirme çalışmalarınında bellek kullanımına el atmadan ya da çöp toplama faaliyetini optimize etmeden sağlıklı bir ölçeklenirlik elde etmek zordur.
  • Üretilen iş (throughput): Belli bir zamanda uygulamanın ürettiği iş miktarıdır. Özellikle toplu yapılan basım, faturalandırma, görüntü işleme, veri aktarımı vb. işlerde çok daha önemli hale gelir, çünkü aslolan bir raporun basılmasının ya da bir abonenin faturasının oluşturulmasından ziyade, belli bir sürede bu işlerden ne kadar çok yapıldığıdır. Bundan dolayı çoğu zaman bu kriter, son kullanıcı cevap zamanı ile çelişen tabiata sahip olur. Örneğin bir abonenin faturasını 10 saniyede üreten bir sistem, bu performans ile son kullanıcısını memnun etmeyebilir. Ama aynı sistem arka tarafta batch olarak, paralel işlem yaparak, saatte 1,000,000 tane fatura üretiyordur ve bu durum son derece kabul edilebilir bir iş üretimi olabilir. Performans iyileştirme çalışmalarınında üretilen işi arttırıcı çalışmalar, uygulamanın mahiyetine göre değişecek şekilde gerekebilir.
  • Başlama zamanı (startup time): Uygulama ilk başlatılırken, kullanıcı isteklerine cevap vermek için hazır oluncaya kadar geçen zamandır. Bu kriter çoğunlukla istemci (client) tarafındaki uygulamalar için önemlidir. Örneğin kendi kişisel makinanızdaki bir kelime işlemcinin iconuna tıkladıktan ne kadar süre sonra kullanıma hazır hale geldiği, son kullanıcılar olara gittikçe daha fazla dikaktimizi çekmektedir. Bundan dolayı örneğin yılardır kullandığımız mekanik hard diskleri, çok daha hızlı olan SSDlerle değiştiriyoruz.  Fakat sunucu (server) tarafındaki uygulamaların örneğin 15-20 dakikada ayağa kalkıyor olması her zaman problem olarak görülmeyebilir. Bundan dolayı bu kriter performans iyileştirme çalışmalarınında genellikle çok da öncelikli olarak ele alınmaz.

Performans iyileştirme çalışmalarında yöntemsiz, gelişi güzel gitmek çoğu zaman sıklıkla karşılaştığımız bir durumdur. Bundan dolayı attığımız taşın ürküttüğümüz kurbagaya deyip deymemesi durumu söz konusudur. Örneğin ortalama olarak 10 saniyede cevap olarak dönen bir arama arayüzünü hızlandırmak için zaman harcayıp sonunda 8 saniyeye indirmiş olmak hiç bir zaman kullanıcı tarafında taktir edilecek bir durum olarak görünmeyecektir. Bu kadar uğreşmak yerine 10 saniye boyunca işlemin durumunu gösteren bir progress bar çıkarmak, son kullanıcıyı, aramanın 8 saniyeye indiği duruma göre daha fazla memnun edebilecektir. Çünkü aslolan son kullanıcının algısıdır. Bundan dolayı son kullanıcı cevap zamanı iyileştirmelerinde, nereye bakmanız, neyi ne kadar iyileştirmenizin gerektiği son derece önemlidir.

Performans iyileştirme çalışmalarında yapılan bir başka yanlış da var olan durumu tespit etmemek ya da edememektir.  Bu durum çoğu zaman teknik bir problem olarak ortaya çıkar. Yani örneğin müşterinin çektiği performans sıkıntısının aynısını üretmekte zorlanırsınız, gerçek ortamda da o sıkıntıyı ölçmeniz zordur. Kendi test ortamınızda ölçüp, iyileştirmeyi yapıp sonra yine aynı şartlarda performansı ölçmeniz gereklidir ki ne kadar yol katettiğinizi anlayabilesiniz. Dolayısıyla ölçüm yapmak, çok sayıda ve aynı şartlarda ölçüm yapmak, olabildiğince ortalamalar üzerinden gitmek, performans iyileştirme çalışmalarının dikkat edilmesi gereken önemli noktalarındandır.

Yöntemden bahsetmişken, basit adımlardan oluşan bir performans iyileştirme sürecinden bahsedebiliriz. Performansı sıkıntılı olan bir yazılım sisteminde iyileştirmeler yapmak için aşağıdaki adımları takip edebiliriz:

  1. Performans problemlerini tanımlamak ve listelemek,
  2. Her bir problemin performansını ölçmek ve iyileştirme hedefini belirlemek,
  3. Problemleri önceliklendirmek,
  4. En yüksek öncelikli problemi ele almak,
  5. Problemin iyileştirme gerektiren noktalarını belirleyip üzerinde çalışmak,
  6. İyileştirilmiş performansı ölçmek,
  7. 5. ve 6. maddeyi, performans hedefini yakalayana kadar tekrar etmek,
  8. 4. maddeden devam etmek.

Bu şekilde bir süreç ile, nereden nereye geldiğimizi belirleyebileceğimiz gibi, değer katan iyileştirmelerde bulunma ihtimalimiz de artmış olur.

Yukarıda tarif edilen süreci kullanarak hedef performans ölçütlerine ulaşmak için temelde üç farklı çözüm şekli kullanılır:

  • Kod değişikliği: Performans olarak sıkıntılı kod parçacıklarını daha etkin çalışanlarla değiştirmektir. Kodda yapılacak değişikliklerle çözüme ulaşmak çoğu zaman en hızlı bulunan ve en hızlı iyileştirilendir. Bu tür kod değişiklikleri hem algoritmik hem de dil tabanlı olabilir. Fakat bu tür değişikliklerin etkisi çoğu zaman azdır.
  • Mimari değişiklik: Yazılım sisteminin alt parçalarınında yapıalcak organizasyonel değişıkliklerdir. Yaygın kod değişiklikleri çoğu zaman kendini mimari değişikliğe çevirir. Mimari değişikliklerin hem maliyeti yüksektir hem de sağladığı iyileştirme oranı çok daha iyidir. Cache kullanmayan bir sistemin cache kullanmaya başlaması ya da veri tabanında örneğin partition kurgulamak vb. yazılım mimarisi değişiklikleri çok sık yapılan iyileştirme çalışmalarındandır. Mimari değişıklikler her zaman kod değişıkliği olarak ortaya çıkmaz, örneğin daha hızlı CPUlara ya da yüksek RAMe sahip olacak şekilde donanım altyapısını iyileştirmek, ağ altyapısını düzenlemek ya da istemcileri güclendirmek de bu tür mimari iyileştirmelerdendir.
  • JVM tuning: Java’nın çalışma zamanı mekanizması olan JVM’in davranışının gözlemlenmesi ve sistemin ihtiyaçlarını karşılayacak şekilde düzenlenmesidir. JVM tuning çalışması, genel olarak JVM’in ayağa kalkarken aldığı parametrelerin düzenlenmesidir. Bu parametreler bellek, çöp toplayıcı, JIT vb. konularla ilgilidir olup genelde her yeni Java SE sürümüyle birlikte ciddi yeniliklerle gelmektedir. Bu amaçla çalışµa zamanında JVM(ler) gözlemlenir, çoğu zaman ayarla-gözlemle-değiştir şeklindeki bir çevrimle parametreler optimum noktaya getirilir. JVM tuningin özellikle gerçek ortam üzerinde, canlıya geçiş öncesinde yapılıp, belli aralıklarla tekrarlanması gereklidir.

Performans ölçümleri dolayısısıyla da gerektikçe performans iyileştirme çalışmaları, bir projenin, yazılım ürününün hayatında farklı evrelerde yapılabilir. Bu evreleri şöyle özetleyebiliriz:

  • Mimariyi kurgularken: Performans ile ilgili en temel çalışmaların yapılması gereken evredir. Elimzide var olan performans ihtiyaçlarını karşılayacak şekilde bir çekirdek mimari kurup, gerekli ölçümleri yapmak ve icap eden değişikliklerden sonra bu çekirdeği nihai mimari olarak kabul etmek, performans konusunda sıkıntı çekmemek için yapılması gereken ilk çalışmadır. Sıkça ıskalananması ile bilinir 🙂
  • Kod geliştiriken: Kritik performans ihtiyaçlarını karşılamada şüphelenilen kod parçalarının daha geliştirilirken ölçülmesi ve iyileştirilmesidir. Dolayısıyla da kodun henüz check in yapılmadan performansının iyileştirilmesi, ilk madde gibi genelde ıskaladığımız ama performans amacıyla yapılacak değişikliğin maliyetini en az seviyede tutan çalışmadır.
  • Test süresince: Fonksiyonel ve performans testleri süresince genelde kod değişikliği ve mimari değişiklikler yerine getirilir. Uygulamanın ölçeklenirliğin belirlenmesi için fonksiyonel testler dışında yük (load) testlerinin de yapılması gereklidir. Test çalışmalarında JVM tuning ile ilgili bazı bulgular da elde edilir ama bu kısma henüz fazla önem verilmez. Dolayısıyla temelde yük testleri söz konusudur. Yük testleri, test otomatizasyon araçları yardımıyla, uygulamaya uygun yük sağlayarak yapılır ve temelde uygulamanın ölçeklenirliğini test etmek için kullanılır.
  • Canlı öncesi: Canlıya geçiş öncesinde, uygulamanın gerçek ortama taşınmasıyla ortaya çıkabilecek yeni performans problemleri ile canlı ortamın JVM mimarisinin ayarlanması ve JVM tuninginin yapılması söz konusudur. Bu amaçla aşağıdaki yoğun yük testler söz yapılır.
  • Canlı sonrası: Canlıya geçiş sonrasında uygulamanın gözlemlenmesi (monitor) ve ortaya çıkan performans problemlerinin giderilmesidir. Bu çalışma daha çok, canlı öncesi oluşturulan JVM mimarisinde iyileştirilmeler yapılmasını gerektirecektir.

Performans problemlerimiz sıkıkla, ıskaladığımız mimari çalışmaların bir bedeli olarak ortaya çıkar ve bu topraklarda genelde donanım altyapısına bol para akıtarak çözülmeye çalışılır. Halbuki bir önceki yazıda verdiğim Facebook örneğindeki gibi sağlıklı mimari çalışmalar ve erken tanılarla bu problem devasa boyutlara çıkmadan önlenebilir.

Performans problemsiz projeler dilerim 😉

Toplam görüntülenme sayısı: 2296

16 Bunu beğendim 🙂
Tweet
Follow me
Tweet to @kaldiroglu
«< 29 30 31 32 33 >»

Günlüğüme Hoşgeldiniz

Bu günlükte, Yazılım Mühendisliği, Bilgi Teknolojileri, Java, kişisel gelişim ve zaman zaman da diğer konulardaki düşüncelerimi sizlerle paylaşacağım. Umarım beğenir ve hoşça vakit geçirirsiniz.

Her türlü düşüncenizi, yorum olsun, beğeni ya da eleştiri olsun, bana iletmenizi rica ediyorum sizden. Ayrıca bana akin@javaturk.org adresinden ya da Twitter'dan ulaşabilirsiniz. Videolarıma da buradan ulaşabilirsiniz.

Teşekkür ederim.

Akın Kaldıroğlu

Rahat Okumak İçin

A Decrease font size. A Reset font size. A Increase font size.

Sosyal Medya

  • Twitter
  • Facebook
  • LinkedIn
  • Youtube

Son Twitlerim

→ Takip Etmek İçin

Abone Olun

Emalinizi girerek yazılardan haberdar olun.
Loading

Son Yazılarım

  • Udemy Eğitimlerim Üzerine
  • (başlıksız)
  • Clean Code / Temiz Kod Eğitimi Udemy’de
  • Java ile Nesne-Merkezli Programlamaya Giriş Eğitimi Udemy’de
  • Selsoft Video Eğitimleri
  • Spring ile Kurumsal Yazılım Geliştirme
  • Corona Günlerinde Design Patterns
  • Corona Günlerinde Java
  • JDK 10 ve “var” Özelliği
  • Onur Özcan
  • Analist ve İş Bilgisi
  • Farklı Dillerin Bakış Açısıyla Nesne-Merkezli Programlama
  • Java Nedir?
  • Bilgi Teknolojilerinde Yetenek Yönetimi – II: Tanımlar ve Eleştiriler – I
  • Alelade Hikayeler – II: Bir Başka Performans Problemi

Yazı Kategorileri

Yazı Takvimi

Mart 2026
P S Ç P C C P
 1
2345678
9101112131415
16171819202122
23242526272829
3031  
« May    

Yazı Arşivi

Blogroll

  • Binnur Kurt'un Günlüğü
  • Ender'in Java Blogu
  • Erdem Seherler
  • Kızımın Günlüğü
  • Kurumsal Java
  • Levent Karagöl
  • Levent'in Java Blogu
  • Mert Can Akkan’s java tips,options, news…
  • Yaşar Safkan
  • Yasin Saygılı
  • Yazı Dünyası

Yazı Etiketleri

analiz Bilmek C Desen design pattern EJB Eğitim Fortran Hibernate Java Java'ya nasil baslarim Java dersleri Java EE Java Persistence API Java SE Java Sertifika Java Öğren Java öğreniyorum Java öğrenmek JPA Kalıp Kurumsal Java nesne nesne-merkezli No Silver Bullet object object-oriented Oracle Java Certifications pattern performans programlama programlama dilleri programlama nedir sertifika singleton tasarım tasarım deseni tasarım desenleri tasarım şablonu yazılım yazılım geliştirme Yazılım Mühendisliği yazılımın doğası yazılımın zorlukları Şablon

↑

© Java Günlüğüm 2026
Powered by WordPress • Themify WordPress Themes
 

Yorumlar Yükleniyor...