ca de m y Java Performansı Online Seminer Akın Kaldıroğlu • • • • w w w .s el so f t.a Java gerçekten yavaş mı? Yoksa developerlar mı yavaş? Dil mi yavaştır yoksa uygulama mı yavaştır? C/C++ kadar hızlı çalışan Java kodu yazılabilir mi? Yüksek performanslı Java kodu yazmak için nelere dikkat etmek gereklidir? • Java ile geliştirilen uygulamalarda sıklıkla görülen performans problemleri ve sebepleri nelerdir? • Java ile geliştirilen uygulamalarda sıklıkla görülen performans problemlerinden nasıl kaçınılır ve nasıl çözülür? www.selsoft.academy ca de m y Küçük Ama Önemli Bir Konu Ø Budosyaveberaberindekitüm,dosya,kod,vb.eğitimmalzemelerinintüm w Ø w Ø w .s el so f Ø t.a Ø haklarıSelsoft Yazılım,Danışmanlık,EğitimveTic.Ltd.Şti.’ne aittir. Bueğitimmalzemelerinikişiselbilgilenmevegelişiminizamacıyla kullanabilirsinizveisteyenlerihttp://www.selsoft.academy adresine yönlendirip,bumalzemelerinengüncelhallerinialmalarınısağlayabilirsiniz. Yukarıdabahsedilenamaçdışında,bueğitimmalzemelerinin,ticari olsun/olmasınherhangibirşekilde,toplubireğitimfaaliyetindekullanılması, buamacayönelikolsun/olmasınbasılması,dağıtılması,gerçekyada sanal/Internetortamlarındayayınlanmasıyasaktır.Böylebirihtiyaçhalinde lütfenbenimle,[email protected] adresindeniletişimegeçin. Buvebenzerieğitimmalzemelerinekatkıdabulunmakyadadüzeltmeve eleştirilerinizibanailetmekistersenizçoksevinirim. BolJava’lıgünlerdilerim. www.selsoft.academy 2 ca de m y JavaYavaş mı? Ø Java,sıklıkla “yavaş”olarak nitelenen bir dil. Buyüzden Javahiç bir zamanC/C++’ınhızına erişemez. el Ø so f t.a Ø Bunu iddia edenlerin temelde iyi dayanağı var: Ø Javanativeçalışmadığı için yavaş olması dazaten normaldir, beklenendir. w w w .s Ø BizJavaile uygulama geliştirdik ve yavaş çalıştı/çalışıyor. www.javaturk.org 3 y ca de m t.a w w w .s el so f Tanımlar www.selsoft.academy 4 ca de m y Yavaş ya daHızlı Olmak Nedir? Ø Uygulamalarda farklı şeylerin performanslarından bahsedebiliriz: t.a (startuptime), Ø Harcanan bellek (memoryfootprint), Ø Cevap verme süresi (responsetime,responsiveness) Ø İş üretme (throughput), Ø Ölçeklenirlik (scalability) w w w .s el so f Ø Ayağa kalkma zamanı www.javaturk.org 5 ca de m y Yavaş ya daHızlı OlanNedir? Ø Hangisinin yavaş ya dahızlı olması,bir uygulamanın yavaş ya dahızlı olmasını daha çok belirler? çalışılan donanım w w w .s Ø Üzerinde el Ø Yazılımın mimarisi so f t.a Ø Dil www.javaturk.org 6 y ca de m Ø Yazılım mimarisi,uygulamaların performanslarını belirlemede enfazla etkiye sahip olandır. so f t.a Ø Buamaçla facebook gibi yüksek ölçeklenirlik gerektiren uygulamaların mimarilerini inceleyebilirsiniz. w w w .s el Ø Ayrıca http://www.javaturk.org/tag/java-performans/ adresindeki yazıma bakabilirsiniz. www.javaturk.org 7 y ca de m Performans Çalışmaları - I Ø Ø so f t.a Ø Performans ile ilgili çalışmalar genelde 3başlık altında ele alınır: Ø Monitoring (gözlemleme):Sistemin davranışını,ona müdahele etmeden ve yük getirmeyecek şekilde, gözlemlemektir. Sistemin tamamı için kullanılır. Daha çok önleyici amaçlar için kullanılır. el Ø Profiling (tarama):Az ya daçok müdahele ederek ve sistemin Ø w Ø Muhtemelen sıkıntılı olduğu düşünülen taraflar için yapılır. Problemolduğunda başvurulur. Sampling(örnekleme)şeklinde daha az müdahele eden şekli de vardır. w Ø w .s davranışı ile ilgili veri toplamaktır. www.javaturk.org 8 y ca de m Performans Çalışmaları - II Ø Tuning (ince ayar):Performansı iyileştirmek amacıyla,kodda, ortamda vs.yapılan ince ayar çalışmalarıdır. t.a Genelde sistemin bütününden ziyade bellialanlara odaklıdır: w w so f Uygulamanın veri tabanı iletişimi ve sorguların (SQL)iyileştirilmesi, Kullanıcı arayüzlerinin inceltilmesi, Sistemin ayağa kalkarken yaptığı işlerin azaltılması, Sistemin XMLişlemesinin iyileştirilmesi, el w .s Ø www.javaturk.org 9 ca de m y Tuning- I Ø Tuningfarklı yerlere ve şekillerde uygulanabilir: Ø Bazen sadece algoritmiktir:Kullanılan algoritma iyileştirilir ya so f t.a dadeğiştirilir. Ø Bazen bellikod parçalarına (aspect)uygulanır:Oturuma w w w .s el konan nesnelerin azaltılması (örneğin HttpSession temizlemesi),veri tabanı iletişimi için Statement yerine PreparedStatement kullanılması,loglama,sorgulama (querying)ya datransactionperformansının iyileştirilmesi. www.javaturk.org 10 ca de m y Tuning- II Ø Bazen teknolojiye uygulanır:JSF1.2’yiJSF2ile değiştirmek gibi. t.a Ø Bazen yazılımın mimarisine uygulanır:Cachekullanımına el so f geçilmesi,nesne havuzu (objectpool)kullanılması ya da yazılımın topolojisinde değişiklik yapılması gibi. Ø Bazan veriye uygulanır:Veri tabanındaki verinin denormalize w w w .s edilmesi ya daveri tabanlarının sağladığı optimizasyon imkanlarının kullanılması. www.javaturk.org 11 ca de m y Tuning- III Ø Bazan donanıma uygulanır:Daha güçlü donanıma geçilmesi gibi. w w w .s el so f t.a Ø Bazan JVM’e uygulanır:Java’ya özel olarak JVM’in davranışını iyileştirmek amacıyla parametreler kullanılır.Buparametrelerin yüksek performans sağlaması amacıyla optimumnoktaya getirilmesidir. www.javaturk.org 12 y ca de m NeZamanTuning? Ø Tuningyapmadan önce,neyin problemli olduğu ve neşekilde iyileştirilmesi gerektiği kesinleştirilmelidir: so f t.a Premature optimizationistherootofallevil– D.Knuth w w w .s el Ø Ayrıca atılan taş,ürkütülen kurbağaya değmelidir. www.javaturk.org 13 y ca de m t.a w w w .s el so f Java Performansı www.selsoft.academy 14 y ca de m JavaYavaş mıdır? so f t.a Ø Javadil olarak yavaş değildir.Çünkü, Ø Javahemen hemen nativeçalışır, Ø Java’nın yorumlanan (interpreted)yapısı,pek çok çalışma zamanı (run-time)iyileştirmesine imkan verir. w .s el Ø Algoritmik performansı göz önüne alırsak,Java’nın C/C++’tandaha yavaş olduğunu söylemek zordur. Ø Buanlamda Java’nın daha yavaş ya dadaha hızlı olduğu Kullanılan algoritmaya dabağlıdır. w Ø w durumsaldır. www.javaturk.org 15 ca de m y Örnekler w w w .s el so f t.a Ø Aynı algoritmayı C++ve Java’da tamamen aynı şekilde yazarak,algoritmik açıdan bu iki dilin performansları karşılaştırılabilir. Ø Butürden karşılaştırmalar uygulama performansı ile ilgili bir şey söylemedikleri gibi sadece algoritmik dil performansı hakkında fikir vermeye yöneliktir. Ø İki örnek: Ø Asal sayıları bulmak için SieveofAtkin, http://www.sanfoundry.com/java-program-sieve-of-atkinalgorithm/ Ø Montecarlo simulasyonu ile PI’ye yakınsamak. www.javaturk.org 16 #include <iostream> #include <stdlib.h> #include <ctime> y so f clock_t start = clock(); t.a namespace MonteCarloPI { using namespace std; int n; int main() { cout.precision(10); int dotsInCircle = 0; cout << "Number of points: " << endl; cin >> n; ca de m MonteCarloPI.cpp (RAND_MAX); (RAND_MAX); w .s el for (int i = 0; i < n; i++) { double x = static_cast<double> (rand()) / static_cast<double> double y = static_cast<double> (rand()) / static_cast<double> double distance = x * x + y * y; if (distance <= 1.0) dotsInCircle++; } } } w w clock_t end = clock(); int time = (int) (1000 * (end - start) / CLOCKS_PER_SEC); double myPi = (double) 4 * dotsInCircle / n; cout << "My PI is: " << myPi << endl; cout << "Time is: " << time << " ms." << endl; return 0; www.javaturk.org 17 package org.javaturk.performance.algorithm.pi; import import import import import import java.util.ArrayList; java.util.List; java.util.Random; java.util.Scanner; org.apache.commons.math.random.BitsStreamGenerator; org.apache.commons.math.random.MersenneTwister; y ca de m MonteCarloPI.java el so f public static void main(String[] args) { System.out.println("*** MonteCarloPI2 ***"); System.out.print("Number of points: "); Scanner in = new Scanner(System.in); n = in.nextLong(); calculatePI(); } t.a /** * Monte Carlo simulation to get closer to PI. It uses MersenneTwister to produce random numbers. * The implementation of this algorithm comes with Apache's commons Math library. */ public class MonteCarloPI2 { private static long n; private static BitsStreamGenerator randomData = new MersenneTwister(); } w w w .s public static void calculatePI() { int dotsInCircle = 0; double start = System.currentTimeMillis(); for (int i = 0; i < n; i++) { double x = randomData.nextDouble(); double y = randomData.nextDouble(); double distance = x * x + y * y; if (distance <= 1) dotsInCircle++; } double finish = System.currentTimeMillis(); double seconds = (finish-start); 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); } www.javaturk.org 18 #include #include #include #include #include "SieveOfAtkin.h" <iostream> <cmath> <vector> <ctime> y ca de m SieveOfAtkin.cpp namespace SieveOfAtkin { using namespace std; int countPrimesUsingSieveOfAtkins(int n) { bool* is_prime = new bool[n + 1]; is_prime[2] = true; is_prime[3] = true; using namespace SieveOfAtkin; using namespace std; int limit = ceil(sqrt(n)); t.a int main() { int n; cout << "Enter the number up to which prime numbers are counted: " << endl; cin >> n; clock_t start = clock(); int numberOfPrimes = countPrimesUsingSieveOfAtkins(n); clock_t end = clock(); int time = (int) (1000 * ((float) end - start) / CLOCKS_PER_SEC); for (int i = 5; i <= n; i++) is_prime[i] = false; so f for (int x = 1; x <= limit; x++) { for (int y = 1; y <= limit; y++) { int num = (4 * x * x + y * y); if (num <= n && (num % 12 == 1 || num % 12 == 5)) is_prime[num] = true; num = (3 * x * x + y * y); if (num <= n && (num % 12 == 7)) is_prime[num] = true; el cout << "Number of primes up to " << n << " : ” << numberOfPrimes << endl; cout << "Time: " << time << " ms." << endl; cout << endl; return 0; w .s } for (int i = 5; i <= limit; i++) if (is_prime[i]) for (int j = i * i; j <= n; j += i) is_prime[j] = false; w w } } num = 3 * x * x - y * y; if ((x > y) && (num <= n) && (num % 12 == 11)) is_prime[num] = true; int numberOfPrimes = 2; for (int i = 5; i <= n; i++) if (is_prime[i]) numberOfPrimes++; return numberOfPrimes; } } www.javaturk.org 19 ca de m y SieveOfAtkin.java package org.javaturk.performance.algorithm.prime; import java.util.Scanner; private static int countPrimesAsUsingSieveOfAtkins(int n) { boolean[] prime = new boolean[n + 1]; prime[2] = true; prime[3] = true; int limit = (int) Math.ceil(Math.sqrt(n)); for (int x = 1; x <= limit; x++) { for (int y = 1; y <= limit; y++) { int num = 4 * x * x + y * y; if (num <= n && (num % 12 == 1 || num % 12 == 5)) prime[num] = true; num = 3 * x * x + y * y; if (num <= n && num % 12 == 7) prime[num] = true; num = 3 * x * x - y * y; if ((x > y) && (num <= n) && (num % 12 == 11)) prime[num] = true; } so f t.a public class SieveOfAtkin { public static void main(String[] args) { System.out.println("Please enter a number to which to list prime numbers:"); Scanner sc = new Scanner(System.in); int n = sc.nextInt(); long start = System.currentTimeMillis(); int numberOfPrimes = countPrimesAsUsingSieveOfAtkins(n); long end = System.currentTimeMillis(); long miliSeconds = end - start; System.out.println("There are " + numberOfPrimes + " prime numbers up to " + n + "."); System.out.println("Time to find them: " + miliSeconds + " ms."); } el } w .s for (int i = 5; i <= limit; i++) if (prime[i]) for (int j = i * i; j <= n; j += i) prime[j] = false; w w int numberOfPrimes = 2; for (int i = 5; i <= n; i++) if (prime[i]) numberOfPrimes++; return numberOfPrimes; } } www.javaturk.org 20 ca de m y Sonuçlar Ø Farklı n girdisi için mili saniye cinsinden Javave C++ programlarının çalışma süreleri şunlardır: 10^6 10^7 38 MonteCarloPI.cpp 21 SieveOfAtkin.java 1,637 24,329 50,486 214 2,404 33,898 81,899 10^7 16 18 2*10^9 10^8 10^9 2*10^9 84 1,025 18,507 47,752 218 2,461 34,871 82,059 w .s SieveOfAtkin.cpp 10^6 el Program 10^9 296 so f MonteCarloPI.java 10^8 t.a Program Ø Busonuçlar 16GBRAMve 8çekirdekli i7CPU’ya sahip,üzerinde ElCapitan w w OSçalışan MacBookProüzerinde elde edilmiştir. Ø Javaiçin JDK1.8.0_25JVM,C++içinkullanılmıştır.Çalışmazamanıiçin tamamenvarsayılanyapılarkullanılmış,hiçbirparametreverilmemiştir. Ø FarklıikiWindows10makinadadabenzersonuçlareldeedilmiştir. www.javaturk.org 21 ca de m y Yorum so f t.a Ø Busonuçlardan çıkabilecek tek şey olsa olsa “Java’nın,C++ kadar hızlı çalışabilir”dir. Ø Busonuçların uygulama performansını değil,algoritmik performansı gösterdiğini unutmayalım. w w w .s el Ø Dolayısıyla “dil olarak Javayavaş”iddiası enazından bu iki algoritma açısından bakıldığında doğru değildir. Ø Java’nın değerlerinin,narttıkça C++’tançok daha iyi hale gelmesi debir tesadüf değildir. Ø Java’nın çalışma zamanı yapısı olan JIT’nin zamanla çok daha etkin çalıştığını göstermektedir. www.javaturk.org 22 ca de m y Uygulama Performansı ve GC- I Ø Önemli olan uygulama performansıdır. so f t.a Ø Javadilinde uygulama performansını etkileyen entemel faktör ise çoğu zamanGarbageCollector(GC)yani Çöp Toplayıcı’dır. Ø GC’nin görevi,nesneleri bellekte oluşturmak ve erişilemeyen w .s el nesneleri bellekten temizlemektir. w w Ø Gelişi güzel yazılmış Javakodunda oluşturulan aşırı sayıdaki nesnenin GCtarafından toplanması,Javauygulamalarının performansı düşüren entemel etkendir. www.javaturk.org 23 ca de m y Uygulama Performansı ve GC- II t.a Ø Dolayısıyla olabildiğince az nesne oluşturmak ya da oluşmasını sağlamak,GC’nin etkisini aza indirmenin en temel yoludur. w .s el so f Ø Belleği etkin kullan,bu amaçla Ø Sadece gerektiği kadar nesne yaratmak ve Ø Nesneleri bellekte sadece ve sadece gerektiği kadar tutmak Ø Dolayısıyla nesneyi tekrar yaratmayı ya dagetirmeyi,nesneyi bellekte tutmaya tercih etmek w w olarak özetlenebilecek stratejiler,Java’nın uygulama performansını arttıracaktır. www.javaturk.org 24 y ca de m EnBasit Enİyi Pratikler - I 1. Stringnesnelerin new ile değil de"" ile oluştur. so f t.a 2. Stringnesnelerini "+"ile değil StringBuilder (threadler varsa ya daStringBuffer)ile değiştir,ekleme vs.yap. w .s el 3. Primitiveleri wrapperlarına tercih et,wrapperları gerekmedikçe kullanma. w w 4. finalizemetodundan uzak dur. www.javaturk.org 25 y ca de m EnBasit Enİyi Pratikler - II t.a 5. Veri yapılarının,torbaların ve algoritmaların karmaşıklıklarından haberdar ol.Örneğin nezaman ArrayList nezamanLinkedList kullanacağını bil. so f 6. Javatorbalarının sık re-sizeetmelerine engel ol. w .s el 7. Nesneleri belekte uzun süre tutmak için concretereferans kullanma,softya daweakrefereansları tercih et. w w 8. Eğer dosya işlemleri yapıyorsanız,özellikle sık okumayazma (mesela filecopygibi)muhakkak bufferkullan. www.javaturk.org 26 y ca de m EnBasit Enİyi Pratikler - III w w w .s el so f t.a 9. Threadve lockmekanizmalarını etkin kullan. www.javaturk.org 27 y ca de m t.a w w w .s el so f Performans Problemlerinden Kaçınmak www.selsoft.academy 28 ca de m y Performans Problemlerinden Kaçınmak - I w w w .s el so f t.a Ø Java’da performans problemlerinden kaçınmak için dikkat edilmesi gereken şeyler şunlardır: Ø Süreç seviyesinde: Ø Performans ihtiyaçlarını sorgulamak ve elde etmek. Ø Kurgulanan mimarinin istenilen performansı yüksek marjla sağlanıldığından,benchmarkingya dasimulasyon vb. yöntemlerle emin olmak. Ø Birim testlerini yapmak ve yapmaya devam etmek, Ø Fonksiyonel testleri yapmak ve yapmaya devam etmek, Ø Performans testleri yapmak ve yapmaya devam etmek, Ø Canlıya geçiş öncesi monitoring,profilingve tuning çalışmalarına kaynak ayırmak. www.javaturk.org 29 ca de m y Performans Problemlerinden Kaçınmak - II w w w .s el so f t.a Ø Teknoloji seviyesinde: Ø Hakimolmadığınız teknolojiyi kullanmamak, Ø Kullanılan teknolojilerin eniyi ve enkötü senaryolarını (best andworstcasescenarios)ve eniyi kullanımlarını ve kalıplarını (bestpractices&patterns)iyi bilmek, Ø Javaseviyesinde: Ø Java’yı iyi bilmek, Ø Java’nın bileşenlerinin eniyi kullanımlarını ve kalıplarını (best practices&patterns)iyi bilmek, Ø JavaAPI’sini etkin kullanmak www.javaturk.org 30 y ca de m so f t.a Sorular Dinlediğiniz için teşekkür ederim. w w w .s el Bu sunuma www.selsoft.academy’den ve www.javaturk.org’dan ulaşabilirsiniz. www.selsoft.academy 31