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
25 Ekim 2015

Java Yavaş mı? : Java’nın Performansı Üzerine – III

Akin Java Java, performans

Bir önceki yazıdan devam edelim ve şimdi de Monte Carlo simulasyonu ile PI’ye yakınsamayı ele alalım.

Önce MonteCarloPI.cpp

/* 
 * File:   MonteCarloPI1.cpp
 * Author: akin
 * 
 * Created on October 7, 2015, 12:39 AM
 */

#include <iostream>
#include <stdlib.h>
#include <ctime>

namespace MonteCarloPI1 {
    
    using namespace std;

    int n;

    int main() {
        cout.precision(10);

        int dotsInCircle = 0;
        cout << "Number of points: " << endl;
        cin >> n;

        clock_t start = clock();

        for (int i = 0; i < n; i++) {
            double x = static_cast<double> (rand()) / static_cast<double> (RAND_MAX);
            double y = static_cast<double> (rand()) / static_cast<double> (RAND_MAX);

            double distance = x * x + y * y;
            if (distance <= 1.0)
                dotsInCircle++;
        }

        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;
    }
}

ve şimdi de MonteCarloPI.java

package org.javaturk.performance.algorithm.pi;

import java.util.Scanner;

import org.apache.commons.math.random.BitsStreamGenerator;
import org.apache.commons.math.random.MersenneTwister;

/**
 * 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.
 * 
 * @author akin
 *
 */
public class MonteCarloPI {
	private static long n;
	private static BitsStreamGenerator randomData = new MersenneTwister();

	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();
	}

	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);
	}
}

 

Monte Carlo simulasyonu ile PI’ye yakınsamak görüldüğü gibi çok daha basit ama çok güzel bir algoritmadır. Random veri oluşturmak dışında son derece basit bir for bloğu içinde bir if cümleciğinden oluşuyor. Random veri için Java’da Apache Commons Math’de bulunan MersenneTwister gerçekleştirmesini kullandım. Buna karşın C++’daki random veri üretimi ise standart kütüphanedeki gerçekleştirmeyi kullandım. Bu farklılığın performansa etkisinin ne kadar olacağını pek kestiremiyorum şu anda, daha fazla araştırmak gerekli.

Bu programın MacBook Pro’mdaki ölçümleri ise şöyle:

Program 10^6 10^7 10^8 10^9 2*10^9
MonteCarloPI.java 38 296 1,637 24,329 50,486
MonteCarloPI.cpp 21 214 2,404 33,898 81,899

 

Bu ölçümlerin de bir önceki SieveOfAtkin‘deki ölçümleri destekliyor olduğu açıktır.

Bu ölçümlerde bir şey dikkatinizi çekiyor mu? Girdi sayısı artarken performans ölçümlerinin Java lehine değişiyor olması bir tesadüf müdür acaba?

 

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

18 Bunu beğendim 🙂
Tweet
Follow me
Tweet to @kaldiroglu
24 Ekim 2015

Java Yavaş mı? : Java’nın Performansı Üzerine – II

Akin Java Java, Java Performans, performans

Bir önceki yazıda kaldığımız yerden devam edelim.

Java Yavaş mıdır?

Java dil olarak yavaş değildir. Çünkü, Java hemen hemen native çalışır. Java’nın yorumlanan (interpreted) yapısının onun performansını hiç bir zaman native çalışan C/C++ gibi diller seviyesine çıkmasına izin vermeyeceği aslında eskimiş, çoktan demode olmuş, geçen yüzyılın bir iddiasıdır. JVMlerin barındırdığı Just In Time (JIT) derleyicileri sık çalışan Java kodlarını çalışma zamanında bulur ve native koda derler öyleki artık bu kodlara yapılan tüm çağrılar native olarak çalışır. Varsayılan değeri 10,000 olan “-XX:CompileThreshold” parametresi bu amaçla kullanılır. Java’nın 1.2 sürümüyle birlikte gelen ve 1.3 sürümünde varsayılan JVM olan HotSpot ismini zaten buradan almaktadır.

Ayrıca Java’nın yorumlanan (interpreted) yapısı ve  pek çok çalışma zamanı (run-time) iyileştirmesine imkan verir. Bu iyileştirmeler nihayetinde HotSpot’ın görevleri arasındadır. Dolayıısyla en azından algoritmik performansı göz önüne alırsak, Java’nın C/C++’tan daha yavaş olduğunu söylemek zordur. Bu anlamda Java’nın daha yavaş ya da daha hızlı olduğu durumsaldır, kullanılan algoritmaya da bağlıdır.

C++ ve Java Performans Karşılaştırması

Bu konuyu iki örnekle göstermek istiyorum. Aynı algoritmayı C++ ve Java’da tamamen aynı şekilde yazarak, algoritmik açıdan bu iki dilin performansları karşılaştırılabilir. Ama unutmayalım ki bu türden karşılaştırmalar uygulama performansı ile ilgili bir şey söylemedikleri gibi sadece algoritmik dil performansı hakkında fikir vermeye yöneliktir.

İlk algoritma asal sayıları bulmak için kullanılan, Sieve of Eratosthenes‘in bir ilerlemiş hali olan Sieve of Atkin algoritması olsun.

Önce SieveOfAtkin.cpp

/* 
 * File:   SieveOfAtkin.cpp
 * Author: akin
 * 
 * Created on October 7, 2015, 12:27 AM
 */

#include "SieveOfAtkin.h"

#include <iostream>
#include <cmath>
#include <vector>
#include <ctime>

using namespace SieveOfAtkin;
using namespace std;

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);

    cout << "Number of primes up to " << n << " : " << numberOfPrimes << endl;
    cout << "Time: " << time << " ms." << endl;
    cout << endl;
    return 0;
}

namespace SieveOfAtkin {
    
    using namespace std;

    int countPrimesUsingSieveOfAtkins(int n) {
        bool* is_prime = new bool[n + 1];
        is_prime[2] = true;
        is_prime[3] = true;

        for (int i = 5; i <= n; i++)
            is_prime[i] = false;

        int limit = ceil(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))
                    is_prime[num] = true;

                num = (3 * x * x + y * y);
                if (num <= n && (num % 12 == 7))
                    is_prime[num] = true;

                num = 3 * x * x - y * y;
                if ((x > y) && (num <= n) && (num % 12 == 11))
                    is_prime[num] = true;
            }
        }

        for (int i = 5; i <= limit; i++)
            if (is_prime[i])
                for (int j = i * i; j <= n; j += i)
                    is_prime[j] = false;

        int numberOfPrimes = 2;
        for (int i = 5; i <= n; i++)
            if (is_prime[i])
                numberOfPrimes++;

        return numberOfPrimes;
    }
}

Şimdi de SieveOfAtkin.java

package org.javaturk.performance.algorithm.prime;

import java.util.Scanner;

/**
 * http://www.sanfoundry.com/java-program-sieve-of-atkin-algorithm/
 * 
 * @author akin
 *
 */
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.");
	}

	private static int countPrimesAsUsingSieveOfAtkins(int n) {
		/** initialize the sieve **/
		boolean[] prime = new boolean[n + 1];
		prime[2] = true;
		prime[3] = true;
		int limit = (int) Math.ceil(Math.sqrt(n));

		/**
		 * put in candidate primes: integers which have an odd number of
		 * representations by certain quadratic forms
		 **/
		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;
			}
		}

		for (int i = 5; i <= limit; i++)
			if (prime[i])
				for (int j = i * i; j <= n; j += i)
					prime[j] = false;

		int numberOfPrimes = 2;
		for (int i = 5; i <= n; i++)
			if (prime[i])
				numberOfPrimes++;

		return numberOfPrimes;
	}
}

Ben bu iki programı bendeki iki ayrı makinada defalarca test ettim. Makinalarım şu özelliklerde:

  • 16 GB RAM ve 8 çekirdekli i7 CPU’ya sahip, üzerinde El Capitan OS çalışan MacBook Pro
  • 8 GB RAM ve 8 çekirdekli i7 CPU’ya sahip, üzerinde Windows 10 çalışan PC

Bu iki programı çalıştırmak için Mac’de Java için JDK 1.8.0_25 JVM, C++ için de XCode 7.1 kullanılmıştır.(Sonradan eklendi: XCode 7.1 varsayılan durumda C++ derleyicisi olarak gcc (GCC) 4.2.x kullanıyor. Ben bu yazıyı yazdıktan sonra makinamdaki GCC’yi en son sürüme yükselttim dolayısıyla artık gcc (GCC) 4.9.2 var ama bu sürümle ölçümleri henüz tekrarlamadım, tekrarlayıp yayınlayacağım.) Çalışma zamanı için tamamen varsayılan yapılar kullanılmış, hiç bir parametre ya da flag verilmemiştir.

Farklı n girdisi için mili saniye cinsinden Java ve C++ programlarının çalışma süreleri şunlardır:

Program

10^6

10^7 10^8 10^9

2*10^9

SieveOfAtkin.java

16

84 1,025 18,507

47,752

SieveOfAtkin.cpp

18

218 2,461 34,871

82,059

 

Bendeki ve arkadaşlarımdaki Windows makinalarda da aynı JVM ve GNU C++ compilerıyla derleyerek yapılan çalışmalarda da yukarıdakine benzer sonuçlar elde ettim.

Sizden ricam, sizin de bu iki programı makinalarınızda çalıştırmanız ve aldığınız sonuçları burada yorum olarak bizlerle paylaşmanız.

Bir sonraki yazıda Monte Carlo simulasyonu ile Pi’ye yakınsamaya çalışacağız 🙂

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

14 Bunu beğendim 🙂
Tweet
Follow me
Tweet to @kaldiroglu
24 Ekim 2015

Java Yavaş mı? : Java’nın Performansı Üzerine – I

Akin Java Java, performans

Giriş

Java, sıklıkla “yavaş” olarak nitelenen bir dil. Hatta pek çok zaman bu durum bir suçlama ve geyik malzemesi olarak da kullanılıyor. Garip olan şu ki bu kanıya sahip olanlar, bu durumu gerçekmiş gibi sunuyorlar. Aslında bunu iddia edenlerin temelde iyi dayanağı var:

  • Java native çalışmadığı için yavaş olması da zaten normaldir, beklenendir. Bu yüzden Java hiç bir zaman C/C++’ın hızına erişemez.
  • Biz Java ile uygulama geliştirdik ve yavaş çalıştı/çalışıyor.

Java is Slow

Aslında analitik olarak gidip, öncelikle yavaş ya da hızlı olmak nedir ona bakmak gereklidir. Uygulamalarda farklı şeylerin performanslarından bahsedebiliriz:

  • Ayağa kalkma zamanı (startup time), bir uygulamanın başladıktan sonra cevap verecek hale gelinceye kadar geçen zamanıdır.
  • Harcanan bellek (memory footprint), uygulamanın bellek tüketimi demektir.
  • Cevap verme süresi (response time, responsiveness), uygulamanın kullanıcıların uygulama üzerinde yaptıkları bilgi girişi, tıklama vs. gibi hareketlerine cevap veriş süresidir.
  • İş üretme (throughput), uygulamanın birim zamanda çıkardığı iştir.
  • Ölçeklenirlik (scalability), uygulamanın yükü arttıkça davranışının değişmesini temsil eden özelliktir.

Bir de şu soruyu sormak lazım: Yavaş ya da hızlı olan nedir? Yani dilin mi hızlı ya da yavaş olmasından bahsedebiliriz yoksa uygulamanın mı? Buna şöyle bir soruyla cevap verelim: Aşağıdakilerden hangisinin performans yönünden kalitesi, bir uygulamanın yavaş ya da hızlı olmasını daha çok belirler?

  • Dilin kendisi
  • Yazılımın mimarisi
  • Üzerinde çalışılan donanım

Yazılım mimarisi, uygulamaların performanslarını belirlemede muhtemelen en fazla etkiye sahip olandır. Bu amaçla Facebook gibi yüksek ölçeklenirlik gerektiren uygulamaların mimarilerini inceleyebilirsiniz. Ayrıca konu ile ilgili buradaki yazıma bakabilirsiniz.

Performans Çalışmaları

Performans ile ilgili çalışmalar genelde 3 baş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 söz konusudur ve daha çok önleyici amaçlar için kullanılır.
  • Profiling (tarama): Az ya da çok müdahele ederek ve sistemin davranışı ile ilgili veri toplamaktır. Muhtemelen sistemin sıkıntılı olduğu düşünülen tarafları için yapılır ve problem olduğunda başvurulur. Sampling (örnekleme) adında daha az müdahele eden şekli de vardır.
  • Tuning (ince ayar): Performansı iyileştirmek amacıyla, kodda, ortamda vs. yapılan ince ayar çalışmalarıdır. Tuning, genelde sistemin bütününden ziyade belli alanlara odaklıdır. Örneğin:
    • 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 XML işlemesinin iyileştirilmesi,

Tuning doğası gereği  farklı yerlere ve şekillerde uygulanabilir. Bir kaç örnek vermek gerekirse:

  • Bazen sadece algoritmiktir: Kullanılan algoritma iyileştirilir ya da değiştirilir.
  • Bazen belli kod parçalarına (aspect) uygulanır: Oturuma konan nesnelerin azaltılması (örneğin HttpSession temizlemesi), veri tabanı iletişimi için Statement yerine PreparedStatement kullanılması, loglama, sorgulama (querying) ya da transaction performansının iyileştirilmesi gibi işlemler bu cinstendir.
  • Bazen teknolojiye uygulanır: JSF 1.2’yi JSF 2 ile değiştirmek ya da Java’in sürümünü arttırıp örneğin 1.5’ten 1.8’e çıkarmak gibi.
  • Bazen yazılımın mimarisine uygulanır: Cache kullanımına geçilmesi, nesne havuzu (object pool) kullanılması ya da yazılımın topolojisinde değişiklik yapılması gibi değişiklikler bu cinsten iyileştirmelerdir. Mimari iyileştirmelerin hem maliyeti yüksektir hem de yüksek risklidirler ama iyi tespit edilip uygulandıklarında ciddi ilerlemeler sağlarlar.
  • Bazen veriye uygulanır: Veri tabanındaki verinin denormalize edilmesi ya da veri tabanlarının sağladığı optimizasyon imkanlarının kullanılması gibi.
  • Bazen donanıma uygulanır: Daha güçlü donanıma geçilmesi ya da kısmi yapılan RAM artışı gibi iyileştirmelerdir.
  • Bazen JVM’e uygulanır: Java’ya özel olarak JVM’in davranışını değiştirmek amacıyla pek çok parametre kullanılır. Bu parametrelerin yüksek performans sağlaması amacıyla optimum noktaya getirilmesi, JVM tuning olarak adlandırılır.

Tuning yapmadan önce, neyin problemli olduğu ve ne şekilde iyileştirilmesi gerektiği kesinleştirilmelidir aksi taktirde daha kötü durumla düşmek isten bile değildir. Bu noktada Donald Knuth’ın sözünü hatırlamakta fayda vardır:

Premature optimization is the root of all evil.

Ayrıca tuning yapılmadan önce, tuning ile kazanılacak performans artışının ne olacağı da kestirilmelidir. Diğer bir deyişle atılan taş, ürkütülen kurbağaya değmelidir.

Bir sonraki yazıda yukarıda Java’nın yavaş olduğundan bahsedenlerin ilk dayanağını ele alacağız.

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

17 Bunu beğendim 🙂
Tweet
Follow me
Tweet to @kaldiroglu
23 Ekim 2015

Java Performansı Semineri

Akin Eğitim ve Seminer, Java

İki hafta kadar önce Java dilinin ve Java ile geliştirilen projelerin performanslarını konu edinen bir seminer düzenledim. İzlanda ile milli maçımızın olduğu geceki bu seminerde katılımcılara “sizi maça yetiştireceğim” diye hızlı teravih imamı söz vermiştim 🙂 Şimdi seminerin sunumunu ve Youtube’da da yayınladığım videosunu paylaşıyorum.

  • Seminerin sunumu

Seminerin videosunu da seyredebilirsiniz:

[embedyt] http://www.youtube.com/embed?listType=playlist&list=UUgKObzoknvY3t-XR_8jlk8g[/embedyt]

 

İyi seyirler.

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

14 Bunu beğendim 🙂
Tweet
Follow me
Tweet to @kaldiroglu
«< 8 9 10 11 12 >»

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

Popüler Yazılar ve Sayfalar

  • Java’ya Nasıl Başlarım? Java’yı Nasıl Öğrenirim? – I
  • Nasıl Yazılımcı Olalım? – II: Hangi Bölümü Okuyalım?
  • Oracle’ın Java SE Sertifikaları: OCA, OCP ve OCM
  • Java Kurulumu ve İlk Programımız
  • İş Analisti İş Tanımı
  • Java Tutorial ya da Kendi Kendine Java Öğren
  • Nasıl Yazılımcı Olalım? – I: Üniversiteli mi Alaylı mı?
  • Tasarım Kalıpları
  • Java’ya Nasıl Başlarım? Java’yı Nasıl Öğrenirim?
  • UML Nedir?

Yazı Kategorileri

Yazı Takvimi

Haziran 2025
P S Ç P C C P
 1
2345678
9101112131415
16171819202122
23242526272829
30  
« 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 2025
Powered by WordPress • Themify WordPress Themes
 

Yorumlar Yükleniyor...