PDA

Tam Sürümünü Görmek İçin : muazzam kutuphane boyutu(Uzun posta)


golgepapaz
23/06/2007, 05:27
yanlis anlasilmasini onlemek yada turkcesini bilemedegim icin bazi terimlerin ingilizcesini
kullanacagim o yuzden simdiden kusura bakmayin. Simdi durum soyle;

elimde oldukca buyuk bir header dosyasi var (6000 satirdan fazla-code generation) ve derleyip bir kutuphanede toplamam gereken 600 kusur tane cpp(yine code generation) dosyasi, bu header'i kendi headerlari araciligiyla #include ediyorlar. header dosyasinda yaklasik olarak 400 class tipi var.Bunlarin bir kismi asagida ki gibi class template'lerin instantiation typedefleri ,bazilari ise bunlarin kompozisyonundan olusan normal C++ siniflari...

template<typename T,Endianness Endian=LittleEndian>
class HLAgeneric :public DataElement
{


public:
typedef typename T valuetype;
HLAgeneric():_value(0){}
HLAgeneric(T val):_value(val)
{
if (HostEndianness!=Endian)
BYTESWAP(_value);
}
HLAgeneric(const HLAgeneric& rhs):_value(rhs._value)
{}
template<typename T2,Endianness Endian2>
HLAgeneric(const HLAgeneric<T2,Endian2>& rhs)
{
this->_value=rhs.getValue();
if(Endian!=HostEndianness)
{
BYTESWAP(_value);
}
}
HLAgeneric<T,Endian>& operator =(T rhs)
{
this->_value=rhs;
if (HostEndianness!=Endian)
BYTESWAP(_value);
return *this;
}
HLAgeneric& operator =(const HLAgeneric& rhs)
{

if (this == &rhs) return *this;
this->_value=rhs._value;
return *this;
}

template<typename T2,Endianness Endian2>
HLAgeneric<T,Endian>& operator =(const HLAgeneric<T2,Endian2>& rhs)
{

if ((void*)this == (void*)&rhs) return *this;

this->_value=rhs.getValue();
if(Endian!=HostEndianness)
{
BYTESWAP(_value);
}
return *this;
}


operator T() const {return getValue();}
virtual int getOctetBoundary() const {return sizeof(T);}
virtual void encode(ByteWrapper& byteWrapper)
{
byteWrapper.put<T>(_value);

}

......
};
yani genel olarak soyle bir yapisi var..


//BigHeader.h
--------------------

typedef HLAgeneric<unsigned char> HLAoctet;
typedef HLAgeneric<short int> HLAinteger16LE;
typedef HLAgeneric<short int,BigEndian> HLAinteger16BE;
typedef HLAgeneric<double,BigEndian> Double1;


class OMT13boolean : public HLAenum<HLAoctet>
{
public:
enum enumerators {
HLAfalse = 0,
HLAtrue = 1,
};
OMT13boolean();
OMT13boolean(const enumerators& rhs);
OMT13boolean& operator = (const enumerators& rhs);
};
struct WorldLocationStruct :public HLAfixedRecord
{
WorldLocationStruct();
WorldLocationStruct(const WorldLocationStruct& rhs);

Double1 X;
Double1 Y;
Double1 Z;

};
Anliyacaginiz gibi sinfilar oldukca basit holder siniflar.Ancak template'lerin dogasi geregi tanimlarini derleyicinin gormesi gerektiginden ve vazgecilmez standart kutuphane ile ve gerekli bir iki boost headeri yuzunden bu headeri sadece include etmek( icinden hic bir seyi kullanmamasina ragmen) object filein sizeni 800kb kadar arttiriyor,bu hesabi 650 cpp dosyasi icin yaparsak bayagi yuklu (yaklasik 800Mb-space optimized,releasemode )kadar object file olusuyor.Buraya kadar okey, sorun su ki linker en sonunda lib dosyasini olustururken tek yaptigi butun bu object file lari paketleyip bana sunmak, boylece elimde dagitamayacagim 800Mb lik bir kutuphane oluyor.

cpp dosyalarinin genel yapisi ise soyle;

classA.h
------------
#include "bigHeader.h"
class A{
public:
const Double1 & getSomeAttribute();
void setSomeAttribute(const Double1& val);
private:
Double1 someAttribute_;
};
classA.cpp
----------
#include "classA.h"

//class A gerceklemesi

classB.h
---------
#include "classA.h"
class B: public A{
public:
void setSomeAttribute(...);
... getSomeAttrubte();
private:
WorldLocationStruct someAttribute_;
...
};
classB.cpp
----------
#include "classB.h"

//class B gerceklemesi
ve boylece surup guduyor, eminim anladiniz.Bu durumda her bir cpp dosyasi ayri olarak bu headeri include ettiginden icindeki linkler olusuyor, ama linkerin bunlari olusturuken yok etmesi gerekmiyr mu? yok etmesi icin ne yapabilirim, header file kucultsem yada ayri dosyalar bolsem(vakit alici), object sizelarim kuculurmu?DLL yapmanin faydasi olur mu? class B de class A dan cok az miktarda ekstra kod icermesine ragmen niye aralarinda 300 kb lik bir fark oluyor.. Olasi fikirleriniz icin simdiden tesekkur ederim


Not: Derleyici olarak VC7.1 kullaniyorum.


acehreli
23/06/2007, 22:01
Eger buyuk baslik dosyasinin icinde yalnizca sablon tanimlari varsa, ama bunlarin turler icin gerceklestirilmeleri gozukmuyorsa, A ve B object dosyalarinin nasil gereksizce buyuk olacaklarini anlayamiyorum.

Hesapta, sablonlar ancak bir derleme biriminde (translation unit) kullanildiklari icin gerceklestirilirler.

O buyuk dosyada ornegin OMT13boolean'in ust sinifi olarak HLAenum<HLAoctet> kullanilmis. O yuzden her derleme biriminde HLAenum<HLAoctet> tekrar uretiliyor.

Bu kodlari otomatik olarak yazan koda erisiminiz var mi? Keske otomatik olarak kucuk kucuk basliklar uretilse ve onlardan hangilerinin gerektigi otomatik olarak uretim sirasinda bilinebilse. Boylece yalnizca gerekli olanlar eklenirdi.

Kutuphane dosyasinin icine bakildiginda ayni semboller birden fazla sayida gorunuyorlar mi? (Bunlari gosteren araclar olmasi gerek.) Baglayicinin sonucta yalnizca bir tanim barindirmasini beklerdim. Eger birden fazla tanim gorunuyorsa, o kutuphane dosyasi yine baska bir aracla "strip" edilebilmeli. Ama boyle bir araci da bilmiyorum.

Ali