Saturday, January 13, 2007

Template C++

Bu postumda size belki biraz sıradışı ama ilginizi çekecek bir konuyu tanıtacağım. Yazıyı okumadan önce C++ ve template bilginizi tazeleyin derim, basit tutucam örneği ama yine de anlamayabilirsiniz:)

Bildiğiniz gibi template kavramı c++ nın güçlü ve önemli bir yanıdır. generic dediğimiz fonksyonlar sınıflar veritipleri oluşturmak için kullanırız genelde. örneğin bir absolute fonksyonu yazacaksak template kullandığımız zaman bütün veri tipleri için ( int float double ... ) ayrı ayrı yazmamıza gerek kalmaz. programcı bir kere yazar bu fonksyonu derleyici sağolsun çevirir....

Benim burada bahsetmek istediğim şey ise daha uçuk bişi:)

Önce gelin template i unutalım ve normal babadan kalma yöntemle bir fibonacci serisinin 20. terimini sadece 50 kere hesaplatalım ve ne kadar zaman alıo ölçelim:

#include < iostream >
using namespace std;

class Fibbooo{
public:
static int FindNth( int n ){
if( n == 0 )
return 0;
if( n == 1 )
return 1;
else
return FindNth( n - 1 ) + FindNth( n - 2);
}
};

int main(){

int result,i;

for( i = 0; i < 50; i++ )
result = Fibbooo::FindNth( 20 );

cout << result;
return 0;
}

Kodun çıktısında 20.terim: 6765 ve en önemlisi toplam süre:

Program Statistics ------------------
Command line at 2007 Jan 14 01:56:
"D:\ITU\c++\fib\Debug\fib"

Total time: 482,825 millisecond
Time outside of functions: 17,381 millisecond
Call depth: 21
Total functions: 1088
Total hits: 1095805
Function coverage: 26,2%
Overhead Calculated 3
Overhead Average 3

Module Statistics for fib.exe
-----------------------------
Time in module: 465,444 millisecond
Percent of time in module: 100,0%
Functions in module: 1088
Hits in module: 1095805
Module function coverage: 26,2%


Görüldüğü gibi modülün yürütülmesi 465,4 milisaniye, tüm program da 482 milisaniye de bitti.

Şimdi gelelim Template Meta Programming e, kodu daha sonra açıklayacağım. önce heycanlanmanız için kodu ve sonucu veriyim. işte kod:

#include <iostream>

template<n>
struct fibonacci
{
enum { result = fibonacci < n-1 >::result + fibonacci < n - 2 >::result};
};

template <>
struct fibonacci<0>
{
enum { result = 0 };
};



template <>
struct fibonacci<1>
{
enum { result = 1 };
};

int main() {

int result,i;

for( i = 0; i < 50; i++)
result = fibonacci<20>::result;

std::cout << result;

return 0;
}


ekran çıktısı bir önceki ile aynı. peki zamanlamalara göz atalım:
Program Statistics ------------------
Command line at 2007 Jan 14 01:59:
"D:\ITU\c++\fib\Debug\template"
Total time: 32,450 millisecond
Time outside of functions: 19,927 millisecond
Call depth: 15
Total functions: 1087
Total hits: 1255
Function coverage: 26,1%
Overhead Calculated 3
Overhead Average 3

Module Statistics for template.exe
----------------------------------
Time in module: 12,522 millisecond
Percent of time in module: 100,0%
Functions in module: 1087
Hits in module: 1255
Module function coverage: 26,1%

Evet, bazılarınız gözlerinize inanamamış olabilir, hatta benim bir yerlerde yannış yaptığımı da düşünebilir:) ama gördükleriniz doğru. program 32,5 milisaniyede ( ilk koda göre yaklaşık 15 kat daha hızlı) modül ise 12,5 milisaniyede ( yaklaşık 35 kat daha hızlı ) bir şekilde çalıştı.

Peki neden? Bunun sebebi aslında çok basit, siz execute tuşuna bastınız, yada exe ye çift tıkladınız, program loader programı belleğe aldı. Aslında tam bu noktada, yani loader programı belleğe yüklerken fibonacci serisinin 20. terimi hazırdı!!! evet hazırdı, program run time da hesaplamaz onu, compile ettiğiniz anda dosyayı 20.terim hesaplanır ve object kodunun içine yazılır. Nasıl mı? template ler compile aşamasında derleyici tarafından değiştirilerek yerine gelmesi gereken kod konulur. örneğin yukarıda bahsettiğim absolute fonksyonunu template ile yazıp, main içerisinde double için fonksyonu çağırırsanız, derlerken derleyici sizin bu fonksyonu double için çağırdığınızı görüp, template ifadelerini atıcak ve yerine sadece double için çalışan absolute fonk. nu yerleştirecektir.

Hal böyleyken, siz derlemeye başladığınız anda derleyici aşağıda ki ifadeyi görecek:
fibonacci<20>::result;
ve fibonacci<20>::result değerini hesaplamaya başlayacaktır. bunun için rekürsif olarak sürekli fibonacci < n > li struct ın değerini hesaplayacak, ne zaman ki n = 0 veya n = 1 olunca fibonacci<0> veya fibonacci<1> in değerlerini ( result değişkenlerini ) alabilecek, ozaman hesaplama bitmiş olacak...

Templateler ile programlama bir çok algoritmayı önemli derecede hızlandırabilmektedir. Uygulama da c++ programları bir run time da hesaplar yapan bölüm, bir de template meta programming dediğimiz bu şekilde kodlama ile yazılır ve compile time denilen yerde işlerin bir bölümü halledilmiş olunur.

Umarım bir miktar açıklayabilmişimdir TMP yi. daha fazlası için bknz google :) Sonraki yazılarımda görüşmek üzere...

No comments: