Tam Sürümünü Görmek İçin : kod performansi
merhabalar...
yazdigim kodun performansini olcebilecegim bir program,teknik...vs biliyor musunuz ?_? ornegin asagidaki ikisi arasindaki calisma hizi farkini ogrenmek istiyorum.
template<typename T>
class equal_to_pixel
: public std::unary_function<T,bool>
{
public:
equal_to_pixel(T pixel) : pixel_(pixel)
{
}
bool operator( )(const T & T_) const
{
return T_ == pixel_;
}
private:
const T pixel_;
};
bool equal_to_pixel(unsigned char ucx)
{
return ucx == 255;
}
turden bagimsiz ve istedigim deger icin kullanabilme luksum tam olarak neye mal oluyor bilmek istiyorum.
Euclides
06/10/2004, 19:30
teknik olarak
başka bir program yazıyorsun o program bunun ne kadar zamanda bu işi yaptığını ölçüyor.
(Programın başlama ile bitiş süresi arası)
nE-nB=süre
Şimdi bazıları mutlaka atlayacaktır. neden kendi kendine değilde başka bir program ile ölçüyoruz diye... Kendi kendine toplam zamanı ölçemez :)
LARGE_INTEGER nB;
LARGE_INTEGER nE;
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si,sizeof(si));
ZeroMemory(&pi,sizeof(pi));
si.cb=sizeof(si);
CreateProcess("hello.exe",NULL,NULL,NULL,false,DEBUG_ONLY_THIS_PROCESS|CREA TE_SUSPENDED,NULL,NULL,&si,&pi);
QueryPerformanceCounter(&nB);
ResumeThread(pi.hThread);
WaitForSingleObject(pi.hProcess,-1);
QueryPerformanceCounter(&nE);
acehreli
06/10/2004, 20:07
Esneklik: C++'in tasarim kistaslarindan birisi, C++ olanaklarinin C esdegerleriyle karsilastirildiginda gereksiz bedeller getirmemesidir.
Onun icin oncelikle, sablon cozumunun getirdigi esnekligin gercekten gerekli olup olmadigina bakmak gerekir. Eger bu esneklik gercekten gerekiyorsa, C esdegerini de buna gore yazmak gerekir:
bool equal_to_pixel(unsigned char const sabit, unsigned char sayi)
{
return sayi == sabit;
}
Sablon parametresi: Sablon parametresini referans olarak yazmisiz. Bunu herhalde o sablonu kopyalanmasi pahali veya olanaksiz olan turlerle de kullanmak icin yapmis olmaliyiz. Eger C esdegerinde de boyle siniflarla calisacaksak, onu da bir referans alacak sekilde yazmamiz gerekir:
bool equal_to_pixel(unsigned char const & sabit, unsigned char & sayi)
{
return sayi == sabit;
}
Eger bu esdeger islev makro olarak yazilmamissa, tanimini baslik kutugu icinde veremeyecegimiz icin, o referanslara erismek icin odeyecegimiz bedelden kurtulamayiz. Cunku, derleyici islevin tanimini goremedigi zaman, islevi cagiran tarafta referans gonderecek sekilde kod yazmak zorundadir. (Tabii eger islevi tamamen bir kutuk icinde tutuyorsak o zaman sorun yoktur; derleyici tanimi gorebilir.)
Eger genelde kopyalanmalari ucuz temel turlerle calisacaksak, sablonu da parametrelerini kopya alacak sekilde yazabiliriz. Ya da temel veya ucuz olan turler icin ozellestirebilir ve onu da ilk yazdigimiz C esdegeri gibi hizlandirabilir. (Yani parametreleri referans olarak degil, kopyalayarak gondermekten bahsediyorum.)
// equal_to_pixel'in unsigned char turu icin ozellestirilmesi (template
// specialization) Artik bu tur icin referans olan parametrelere erisme
// bedelinden kurtulmus oluyoruz.
//
// Yani T yerine 'unsigned char' yazdim ve operator() islecinin
// parametresini kopya olarak gonderdim.
template<>
class equal_to_pixel<unsigned char>
: public std::unary_function<unsigned char,bool>
{
public:
equal_to_pixel(unsigned char pixel) : pixel_(pixel)
{
}
bool operator( )(const unsigned char T_) const
{
return T_ == pixel_;
}
private:
const unsigned char pixel_;
};
Benim fikrim: Bu isi kesinlikle once islev olarak yazmak ve ancak o esneklige gerek duyuldugunda tekrar sablon olarak gerceklemek gerekir. Extreme Programming de boyle soyler ve ileride belki gerekir diye kod yazmanin zaman kaybina neden oldugunu formullerle kanitlar. Martin Fowler da 'refactor mercilessly' (kodu acimadan degistirin) fikrinin babasidir.
Bu kadar laf salatasindan sonra asil soruya geldim :) Program performansini olcmek icin aklima gelen bir kac tane yol soyle:
1) Kullanilan ortamin 'profiler'ini kullanmak. Gnu'nun gprof'u var... VC++'in da bir 'profiler'i oldugunu biliyorum. Baska derleyicilerin de mutlaka vardir.
2) Islevi cagirmadan once zaman olculur, islev bittikten sonra zaman tekrar olculur :) Zamani olcmek icin clock, gettimeofday veya daha yuksek duyarlikli bir islev kullanilabilir.
Ama ne olursa olsun, islevi cok sayida cagirmak iyi olur:
Zaman baslangic = zamani_olc();
for (int i = 0; i != buyukBirSayi; ++i)
{
/* yapilan is */
}
cout << "sure: " << zamani_olc() - baslangic;
Benim dusuncem: Bence sablon secenegi, gerceklemeyi baslik kutugune koydurabildigi icin C esdegerinden daha hizli cikacaktir. Derleyici islevin tanimini gorebildigi icin eniyilestirme konusunda daha basarili olacaktir.
Baska bir yol: Derleyicinin olusturdugu assembly dili ciktilarini karsilastirmaktir.
Bazen, yavas calisan bir programin yavasligi konusunda belirli bir islevden supheleniriz. Boyle bir durumda suphenin ne kadar dogru oldugunu anlamak icin cok ucuz bir yontem vardir: Supheli islevi, yaptigi isi iki kere yapacak sekilde degistirmek... (Bu aslinda her durumda o kadar kolaylikla kullanilamaz, cunku her isi iki kere yapamayabiliriz. Ornegin, ag baglantisi...)
void supheli()
{
{
/* asil is */
}
{
/* ayni is bir kere daha */
}
}
Bunu yapmak gercekten programin hizini cok fazla yavaslatiyorsa, evet, bu islevi hizlandirmaya calismak cok ise yarayacaktir.
Ali
Forum Yazılımı : vBulletin v3.6.8, Copyright ©2000-2008, Jelsoft Enterprises Ltd.