usability comparision for usual programming languages
Javy'nin tam imla yapısı oturmadan çeşitli kullanılabilirlik testleri ile durumu ele almak istiyorum. Bu şekilde daha kolay ve anlaşılır program geliştirme metodunu yakalayabiliriz sanırım. Bu testi yaparken sıralama algoritmalarından bubble sort algoritmasının codecodex.com adresindeki örnekleri üzerinde incelemeler yapmak istiyorum.
Assembly Dilinde Kabarcık Sıralama
bs proc array:DWORD,len:DWORD
mov ecx,len
mov edx,array
bs_o:
xor ebp,ebp
bs_i:
mov eax,DWORD PTR [edx+ebp*4+4]
cmp DWORD PTR [edx+ebp*4],eax
jb @F
xchg eax,DWORD PTR [edx+ebp*4]
mov DWORD PTR [edx+ebp*4+4],eax
@@:
add ebp,1
cmp ebp,ecx
jb bs_i
loop bs_o
pop ebp
retn 8
bs endp
Aslında yukarıdaki ifade tam bir assemly dili değil. Assembly derleyicisinin (Assembler), belirli bir adrese etiket atama ve offsetler üzerinde aritmetik işlemler yapabilme gibi çeşitli güzel özellikleri ile Assembly dili bir nebze olsun daha kullanıcı dostu hale getirilmiş. HLA (High Level Assembly) adındaki çeşitli projeler sayesinde Assembly dili kodları arasında if, else gibi çeşitli üst düzey ifadeler yazabilmekteyiz. Assembly makine kodlarının anlaşılabilir hale getirilmiş hali olduğu için çok yüksek hızlarda işlem yapabilmekte. Makine dili ve özellikle üst düzey hali (HLA) paylaşılmış kütüphaneler ve durağan kütüphanelerdeki API'leri kullandığı sürece uzun kodlar nispeten daha da kısaltılmış oluyor. Fakat işlemci üzerindeki kaydedicilerin varlığından bile haberdar olmayan programcılardan EAX kaydedicisinin içeriğini yığına atmalarını beklemek hem üretkenliği hem de geliştirici sayısını azaltacaktır.
C Dilinde Kabarcık Sıralama
void bubbleSort(int *array, int length)
{
int i, j, temp;
int test; /*use this only if unsure whether the list is already sorted or not*/
for(i = length - 1; i > 0; i--)
{
test=0;
for(j = 0; j < i; j++)
{
if(array[j] > array[j+1]) /* compare neighboring elements */
{
temp = array[j]; /* swap array[j] and array[j+1] */
array[j] = array[j+1];
array[j+1] = temp;
test=1;
}
} /*end for j*/
if(test==0) break; /*will exit if the list is sorted!*/
} /*end for i*/
}/*end bubbleSort*/
Assembly dilini insancıl hale getiren en önemli dil hiç şüphesiz C dilidir. Statik bir dilde yani derleme işlemi yapacağımız bir dilde derleme süresinin önemi, Dinamik bir dilin çalışma süresinin önemine kıyasla daha azdır. Eğer yazdığınız bir program 15 sn'de derleniyor ve diğer programlama dillerinin çoğunun veremediği performansı veriyor ise buna katlanabiliriz. -Ki Durağan dillerde modüllere ayrılmış bir yapı ve make ya da ant gibi derleme konusundaki yardımcı araçlar sayesinde. Yalnızca üzerinde işlem yapılan modül derlenebilir. Bu da derleme süresi yavaş olan bir dilde bile harika bir süre tasarrufu demektir. Bu manada dilin imlası derleme süresini arttırsa bile önemli olan üretkenliği de arttırmasıdır.
C dilinin eksilerinden biri ";"'dür. Aynı hataya düşen bir çok programlama dili mevcut. (PHP, Perl, Java, JavaScript, C# ....) Python bunu eğer aynı satırda iki farklı ifade kullanacaksanız ";" kullanabilirsiniz şeklindeki akılcıl çözümü ile ele almış. Zaten LF yada CR'ın çeşitli kombinasyonları ile satır sonu ayraçları bulunmakta. Noktalı Virgül'e bu manada gerek bulunmuyor.
C'nin çok satırlı yorum ifadesi ise Python'a veya çok satırlı yorum ifadesi bulunmayan diğer dillere göre bir üstünlük diyebiliriz. Fakat Python API belgelemesi için 3 tırnak arasına istediğimiz kadar satır girmemize olanak sağlayarak bu olayı kendi meşrebince çözmüş. Yani Guido diyorki eğer çok satırlı yorum yapacaksanız; Bunu API dökümantasyonu yapın. E haklıda biraz olsun. Fakat programcı çok satırlı bir yorum ile anında bir kod bloğunu saf dışı bırakabilir. Bu da gösteriyorki yeni nesil bir dilde her ikisi de bulunmalı. Özellikle Dinamik yani devingen bir betik dil ise "#" yorum ifadesine kesinlikle sahip olmalıdır. Bu ifade betiğin UNIX sistemlerinde bash tarafından işlenebilmesine olanak tanınacaktır.
Kişisel fikrim değilşken tiplerinin belirlenmesi hızlı uygulama geliştirmenin en önemli engellerinden biridir. Bir değişkenin tipinin programcı tarafından belirlenmesi derlenme süresini kısaltacaktır fakat kullanıcıya ait program kodları daha uzun bir hal alacaktır. Değişken tiplerinin belirtilmemesinin (duck typing) dezavantajı ise Java'nın sağladığı gibi bir polymorhism'e sahip olunamayacaktır. Python'da aynı isimde iki method veya işlev bu manada tanımlayamamaktayız. Bu Java gibi dillerde sanal işlev tablosu ile sağlanmakta. Bu manada bir çok biçimliliği python desteklememekte. Her iki özelliği de elde etmek için işlevlerde gerektiğinde durağan tanımlamaların da yapılabildiği dinamik bir dil tercihimdir.
PHP Dilinde Kabarcık Sıralama
function BubbleSort( $items ) {
$temp = "";
$size = count( $items );
for( $i = 0; $i < $size-1; $i++ ) {
for( $j = 0; $j < $size - 1 - $i; $j++ ) {
if( $items[$j+1] < $items[$j] ) {
$temp = $items[$j];
$items[$j] = $items[$j+1];
$items[$j+1] = $temp;
}
}
}
}
C hakkında olan tüm eleştirilerimiz PHP içinde geçerli tabiki :) PHP'nin ek olarak alışılmadık bir işlev sistematiği bulunmakta hemen hemen tüm işlevler hiçbir ad uzayı veya paket altında bulunmuyor. İsmini yazdığınız işlevi hemen çağırabiliyorsunuz. Hiçbir paket ya da ad uzayı (namespace) kullanılmadan işevlere direkt erişebiliyorsunuz. Fakat bu sistem, ad karmaşasını da beraberinde getiriyor. PHP'de İşlevler bir sinif içerisinde dahi değiller. Doğrudan erişim esas alınmış. Bunun için php işlevleri, konusuna göre çeşitli önekler alıyor. Mesela mysql hakkındaki bir işlev "mysql_" önekini alıyor. Bu yaklaşım yorumlayıcı hızını düşürmekte esasen ve isim kirliliğini önlemek için de zaten önekler kullanılıyor. Bu manada sinif.metod() çağırımı ile sinif_metod() çağırımı arasında kod uzunluğu bakımından pek bir fark bulunmuyor.
PHP'nin perl ile benzer bir yaklaşımı daha mevcut değişken tanımlama. Değişkenlerin başına dolar ifadesi konuluyor. Bu başlangıçta bana çok saçma gelmesine karşın. Daha sonraları değişken değişkenleri görünce mantıklı gelmişti. Örneğin $a = deneme ise $$a deneme isimli bir değişkene işaret etmekte. Fakat a = "deneme" $a deneme değişkenine eşit olsaydı daha mantıklı bir yaklaşım olacaktı.
Java Dilinde Kabarcık Sıralama
//Sorts an integer array in ascending order.
//Notice that the array passed must not be a null reference.
//Parameters:
// data[] - the integer array to sort
//Postcondition:
// The array is sorted in ascending order.
public static void bubbleSort(int[] data)
{
boolean isSorted;
int tempVariable;
int numberOfTimesLooped = 0;
do
{
isSorted = true;
for (int i = 1; i < data.length - numberOfTimesLooped; i++)
{
if (data[i] < data[i - 1])
{
tempVariable = data[i];
data[i] = data[i - 1];
data[i - 1] = tempVariable;
isSorted = false;
}
}
numberOfTimesLooped++;
}
while (!isSorted);
}
C tarzı dillerin çeşitli güzellikleri de yok değil. Örneğin kıvırcık parantezler tüm programı tek satırda ifade etmemize bile olanak sağlamakta. Ayrıca ++, ! gibi operatörler ise programı oldukça kısaltmakta.
Python'da Kabarcık Sıralama
def bubblesort(l):
"Sorts l in place and returns it."
for passesLeft in range(len(l)-1, 0, -1):
for index in range(passesLeft):
if l[index] < l[index + 1]:
l[index], l[index + 1] = l[index + 1], l[index]
return l
Python harika operatörleri gereği bu işin üstesinden kolaylıkla geliyor. Fakat girintileme zorunluluğu programcıları iyi bir yöne doğrulturken bazen de yapmak istediklerinizi kısıtlayabiliyor. Bu konuda da ruby imdada yetişiyor.
Ruby'de Kabarcık Sıralama
def bubble_sort(list)
list = list.clone # we should not modify original list
for i in 0..(list.length - 1)
for j in 0..(list.length - i - 2)
list[j], list[j + 1] = list[j + 1], list[j] if ( list[j + 1] <=> list[j] ) == -1
end
end
return list
end
Ruby girintileme kaprisi olmayan nesne modelli bir dil. Ve yazdığınız kodlar son derece okunulabilir olmakta. "in" gibi Python tarzı operatörleri de oldukça işlevsel. Ama if .... end tarzı yaklaşımdan ziyade C tarzı kıvrık parantezler daha hızlı ayrıştırılabilmekte.
|