dizge birleştirmenin anatomisi | | Tuesday, June 27, 2006 2:09:00 AM tarihinde Fırat KÜÇÜK tarafından gönderildi. | Bazen yazdığınız bir kaç satır karakter katarını "+" operatörü ile birleştirmek isteyebilirsiniz. Peki javada bu işlem nasıl yapılıyor? Neler yaparsak daha hızlı bir kod yazarız?
class KatarBirlestirme {
public static void main(String args[]) {
System.out.println("merhaba" + " " + "dunya");
}
}
jad ile yazdığımız ve derlediğimiz kodları geri dönüştürürsek analiz edebiliriz. String nesnesi Immutable (değiştirilemez) olduğundan karakter katarı birleşimlerini java StrinBuffer nesnesi dönüştürerek yapar. Ama derleyici hızı açısından burada JVM'in hepsini tek katar olarak düşünmesi beklenir. (Yani ben olsaydım böyle yapardım.) İşte JAD ile geri dönüştürdüğümüz kod:
// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/kpdus/jad.html
// Decompiler options: packimports(3)
// Source File Name: KatarBirlestirme.java
import java.io.PrintStream;
class KatarBirlestirme
{
KatarBirlestirme()
{
}
public static void main(String args[])
{
System.out.println("merhaba dunya");
}
}
Tadaaa .. 10 puan, 10 puan, 10 puan, 10 puan ... JVM'e 10 puan zeki bir yaratık optimizasyonu böyle yapar. Peki olayı biraz çetrefilli hale getirip değişken de ekleyelim.
class DegiskenliKatarBirlestirme {
public static void main(String args[]) {
String degisken = " dunya";
System.out.println("merhaba" + degisken);
}
}
Ve sonuç ...
// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/kpdus/jad.html
// Decompiler options: packimports(3)
// Source File Name: DegiskenliKatarBirlestirme.java
import java.io.PrintStream;
class DegiskenliKatarBirlestirme
{
DegiskenliKatarBirlestirme()
{
}
public static void main(String args[])
{
String s = " dunya";
System.out.println((new StringBuilder()).append("merhaba").append(s).toString());
}
}
Burada aklımıza şu soru geliyor. Tüm bunları incelemem için beni gaza getiren Sun dökümanında şu ifade geçiyor: Use StringBuffer to Concatenate Strings Karakter katarlarını birleştirmek için StringBuffer kullanın. Derleyici benim yerime bu işlemi yapıyorsa ben neden bununla vakit geçireyim. Tamam derleme süresini 10 ms uzatabilir ama sonuçta derlendikten sonra benim kodum ve derlenen kod aynı işlemi yapmış olacak. Üşenmedim bir de aynı işlemi ben yapayım dedim, Ve ByteCode düzeyinde olayı irdeleyelim. Bir Önceki sınıfın [[http://www.cs.princeton.edu/~benjasik/dis/|dis]] ile disassembly edilmiş hali:
super synchronized class DegiskenliKatarBirlestirme extends java/lang/Object
Method <init> () -> void
0 aload_0
1 invokenonvirtual #1 <Method java/lang/Object.<init> ()V>
4 return
Method public static main (java/lang/String []) -> void
0 ldc #2 <String " dunya">
2 astore_1
3 getstatic #3 <Field java/lang/System.out Ljava/io/PrintStream;>
6 new #4 <Class java/lang/StringBuilder>
9 dup
10 invokenonvirtual #5 <Method java/lang/StringBuilder.<init> ()V>
13 ldc #6 <String "merhaba">
15 invokevirtual #7 <Method java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;>
18 aload_1
19 invokevirtual #7 <Method java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;>
22 invokevirtual #8 <Method java/lang/StringBuilder.toString ()Ljava/lang/String;>
25 invokevirtual #9 <Method java/io/PrintStream.println (Ljava/lang/String;)V>
28 return
Kodumuzu StringBuffer kullanarak yazarsak
class TamponluKatarBirlestirme {
public static void main(String args[]) {
String degisken = " dunya";
System.out.println((new StringBuffer("merhaba")).append(degisken).toString());
}
}
java assembly hali
super synchronized class TamponluKatarBirlestirme extends java/lang/Object
Method <init> () -> void
0 aload_0
1 invokenonvirtual #1 <Method java/lang/Object.<init> ()V>
4 return
Method public static main (java/lang/String []) -> void
0 ldc #2 <String " dunya">
2 astore_1
3 getstatic #3 <Field java/lang/System.out Ljava/io/PrintStream;>
6 new #4 <Class java/lang/StringBuffer>
9 dup
10 ldc #5 <String "merhaba">
12 invokenonvirtual #6 <Method java/lang/StringBuffer.<init> (Ljava/lang/String;)V>
15 aload_1
16 invokevirtual #7 <Method java/lang/StringBuffer.append (Ljava/lang/String;)Ljava/lang/StringBuffer;>
19 invokevirtual #8 <Method java/lang/StringBuffer.toString ()Ljava/lang/String;>
22 invokevirtual #9 <Method java/io/PrintStream.println (Ljava/lang/String;)V>
25 return
Burada benim yazdığım kod daha yavaştır çünkü aynı işlemi StringBuffer sınıfı ile yapmaktayım. Fakat J2SE 1.5 ile gelen StringBuilder sınıfı JVM 1.5 tarafından otomatik kullanılmış. Eee buradan çıkaracağımız ders. Aynı şekilde kod yazmaya devam edin. Burda yazılanları bilmeseniz de olurdu. :)
| | atölye, inceleme, java | kaynak |
yorumlar [0]
|
servlet'in alamet-i farikası | | Tuesday, June 20, 2006 6:14:00 AM tarihinde Fırat KÜÇÜK tarafından gönderildi. | Bu aralar hepinizin de bildiği üzere. Ya da bizim çokça zikrettiğimiz üzere; bir java serüvenidir ki gidiyor. Ee, her zaman yeni bir şeyler öğrenmeli, koşmalı, koşamıyorsa yerinde zıplamalı. Biz de bunu, destur edinerek başımıza böyle işler açıyoruz. Açarken de günlüğümüzü çiziktiriyoruz ki; ne maymunluklar yaptığımızı görün.
Bu gün bol bol servlet, koddum. (koddum, koddun, koddu yani i code, you code, he/she/it codes) EE, artık açık kaynak tabi :) Tiger kod adlı java 5.0 ile yolumuza dolu dizgin devam ediyoruz. Yalnız ! Bugün sıyırmama neden olan bir olay ile karşılaştım; HttpServlet sınıfından miras aldığımız ve çiğneyip, ezip geçtiğimiz (override) doGet metodunun get ile gönderilen istekleri tuttuğunu, servlet ile uğraşan herkes bilir. Tanımladığım bir Vector tipli değişken için addElement metodunu, doGet metodu içinden çağırdım. İşte sıyırma belirtileri tam burada başladı. Vector değişkeninin içine attığım veriler bir çok kez tekrar ediyordu. Bunun, oluşturduğum servlete giden parametre miktarınca olduğunu düşündüm ilk önce. Servlet?a=1&b=2&c=3 gibi bir örnek ifadenin, 3 parametre gittiğinden 3 defa doGet metodunu çağırdığını ve bundan dolayı olduğunu sandım evvela.
Ama, cıkk! Öyle değilmiş durum. Çünkü dizimizin boyutu git gide artmaktaydı. Bunu, servletimizin başına private int counter = 0; diye bir sayaç ekleyerek test etmeye karar verdim. doGet metodunun içine de o meşhuuuur: counter++; ifadesini yazdım.
İşte dananın kuyruğunun koptuğu an buydu! Her f5 tuşuna basışımda sayaç bir artıyordu! Bir oturum değişkeni değildi. Sunucuya ait küresel bir değişken de değildi. Yav PHP'de, Python'da böyle bir şey yok! C# programladığım zamanlar da bu tarz birşey ile karşılaşmamıştım. Hem de private bir değişkenin bu denli beni madara etmesi bende geçersiz işlem yürüttü.
Olayın kaynağı tabiki yine cehaletmiş. Servletin çok kanallı (multi-thread) olduğunu biliyoruz. Lakin gelen isteklere nasıl yanıt verdiği konusunda cehaletimiz sürmekteymiş. Efenim! Normal bir PHP betiğine gelen her istek (request), Apache'de bir alt süreç (child process) oluşturur. Bu alt süreçler, talep edilen PHP betiğini çalıştırır. Apache, kendisine istek gelmediği zaman, KeepAlive seçili ise, KeepAlive zaman aşımı süresince yeni istekleri bekler. Eğer istek gelmez ve KeepAlive süresi dolar ise PHP alt süreci, Hakk'ın rahmetine kavuşur. CGI'da da bu yaklaşım aynıdır. Fast-CGI'da ise tüm istekler için tek bir alt süreç oluşur. Fakat Servlet denilen meretin çalışma prensibi bunlardan hiçbirine uymamakta ki değişken sürekli etkin kalmaktaydı!
Efenim! Servlet sunucusu tek süreç ile çalışmaktadır. Bu süreç, kanalları vasıtası ile servletleri çağırır. Çağrılan servletler isteklere yine aynı metod ile cevap verirler. Bu sayede hızlı bir çalışma mekanizması kazanılır. Servlet ilk çalıştığında; init metodu çalışır. Ve servlet çalışmaya devam eder. Her gelen istek doGet veya doPost metodunu çağırır. Böylelikle değişkenimiz uygulama kapanana kadar işlevini yerine getirir.
Buna göre kolayca bir vuru ziyaretçi sayacı (hit counter) yazabiliriz. Bu sayaç, sayfaya gelen istek sayısını gösterir.
import java.io.*;
import javax.servlet.http.*;
public class Sayac extends HttpServlet {
private int sayac;
public void doGet(HttpServletRequest istek, HttpServletResponse cevap)
throws IOException {
sayac++;
PrintWriter sayfa = cevap.getWriter();
sayfa.println(sayac);
sayfa.close();
}
}
| | atölye, inceleme, java | kaynak |
yorumlar [1]
|
python'a semer vurulamıyormuş. | | Monday, June 19, 2006 7:18:00 AM tarihinde Fırat KÜÇÜK tarafından gönderildi. | Java maceramız tüm hızıyla sürerken Python'daki bir sınıfın metodlarının aşırı yüklenmediğini (overload) farkettim. Aynı adda iki metod oluşturunca python en son yazdığınızı geçerli kılmakta:
#! /usr/bin/python
# -*- coding: UTF-8 -*-
class AsiriYuklemeTesti:
def metod(self, arguman): return arguman
def metod(self, arguman1, arguman2): return arguman1
test = AsiriYuklemeTesti()
print test.metod("yazdir bakalim")
İşte python yorumlayıcısının cevabı:
Traceback (most recent call last):
File "./oveload.py", line 11, in ?
print deneme.metod("yazdir bakalim")
TypeError: metod() takes exactly 3 arguments (2 given)
Peki Java'da durum nasıl?
class Overload {
public static void main(String[] argumanlar) {
AsiriYuklemeTesti test = new AsiriYuklemeTesti();
System.out.println(test.metod("hadi bakalim hayirlisi"));
}
}
class AsiriYuklemeTesti {
public String metod(String arguman) {
return arguman;
}
public String metod(String arguman1, String arguman2) {
return arguman1;
}
}
Ama java kullananlar da sevinmesin. Javada da işleç (operator) aşırı yüklemesi bulunmuyormuş. Ama C#'ta bulunuyor.
| | inceleme, java, python | kaynak |
yorumlar [1]
|
gcj ile jre'den bağımsız uygulamalar | | Sunday, June 18, 2006 10:29:00 PM tarihinde Fırat KÜÇÜK tarafından gönderildi. | Java'da yazılmış bir program elimize geçti. Hemen çift tıklayıp çalıştırmayı deneriz. Fakat dosya ilişkilendirilmediği için çalışmayacaktır. Tabi bir .class dosyasının ilişkilendirilmesi çok ta mümkün olmuyor. İlişkilendirilse bile main metodu bu sınıfta mevcut mudur? Bu da büyük bir sorun. Sanırım en mantıklısı yazdığımız programları .jar dosyası yapmak. Bu sayede programları hem Linux'ta hem de Windows'ta kolayca ilişkilendirebiliriz. java -jar ornek.jar yazıp çalıştırabiliriz. Ama yazdığımız programlarda kullanıcıları ilişkilendirme ile uğraştırmak istemiyorsak: en kolay yol; JNLP uzantılı web start dosyası oluşturmak olacaktır.
Fakat ne yaparsak yapalım sistemde bir JRE (Java Çalışma Zamanı Ortamı) olmadığı sürece yazdığımız hiç bir program çalışmayacaktır. Java ile yazdığımız programları java bytecode'larını es geçerek direkt makine diline derlememiz gcj ile mümkün. Bu sayede çift tıklayıp çalıştırabileceğimiz. JRE gerekmeyen programlarımız olacaktır. (Native Code Compilation) Yerel Kod Derlemesi olarak adlandırabileceğimiz işlem şu şekilde yapılmakta:
import javax.swing.JFrame;
class Ornek extends JFrame {
public static void main(String[] args) {
Ornek program = new Ornek();
program.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
program.setLocation(300, 300);
program.setSize(300, 300);
program.setVisible(true);
}
}
Swing kullanan bu programı Ornek.java adıyla kaydedip:
gcj --main=Ornek -o Ornek Ornek.java
yazıyoruz. Hepsi bu kadar :) Artık başına java yazmadan kodlarımızı çalıştırabiliriz.
./Ornek.java
| | atölye, inceleme, java | kaynak |
yorumlar [0]
|
debiancılara bir şeyler oluyor | | Wednesday, June 7, 2006 9:41:00 AM tarihinde Fırat KÜÇÜK tarafından gönderildi. | Bu aralar etrafımda gördüğüm tüm debiancılara bir şeyler oluyor. Tabi sen debianın neresindensin derseniz. Ben içinden değilim; köyündenim. Yoksa kabilesindenim mi desem :) Çünkü afrikalı dağıtım ubuntuyu kullanıyorum. Neyse uzun lafın kısası debian kullanan programcı arkadaşları bir java merakı sardı. Ben, c-star'ı java ile yazmaya karar verdim. Sonra Yılmaz tüm şirketini javaya geçirdi. (Gaza getirme konusunda çok başarılıdır.) Ve sonra orta-doğu ve balkanların en iyi sistemcisi Cafer javaya geçti.
Ben sadece javaya geçmekle kalmayıp, java studio enterprise kullanmaya başladım. Sağolsun Yılmazın gazı ile :) Tam da gedit'e python eklenti desteği eklenmişti. Allah, sonumuzu hayır etsin. Bu java harekatının en büyük nedeni; Javanın açık kaynak saflara geçmesiydi. Aybiem abi, sun'a şöyle demiş; Sun, bak sana diyorum evet Sun'a diyorum; gel bu javayı açık kaynak yapalım. Tut şu işin ucundan he de, sevenleri ayırma, Sonra onlar ermiş muradına biz çıkalım kerevetine.
Şimdi gelsin mobility pack ile cep telefonumuzda çalışan uygulamalar. Ama gönlüm hala python'da :) Neyse ben bu konuda biraz arsızım sanırım en büyük hobim yeni bir programlama dili öğrenmek.:) Neyse herkese tavsiye ediyorum. Özellikle UML tabanlı uygulama yapmak bir harika :) Yeni mikropyuvası'na geçince bu konuda bir makale yazabilirim belki.
| | linux, yorum | kaynak |
yorumlar [1]
|
1
|