Sign in to follow this  
DeadXorAlive

why is this so bloated?

Recommended Posts

Hi, finally I have solved some problem by making a factory method using templated functions objects with boost, it was not fun but it works. Now I was suprised that storing only 6 functors in a map caused my exe to grow with 120Kb! Maybe I am doing something wrong, how can this be so bloated or is it normal? And will it be a problem? This is the function object:
template <class T>
struct OneStyle
{
    BaseWidget* operator()( const std::string& WidgetType,
                            const Rect<int>& Viewport,
                            const std::string& Name )
    {
        if (WidgetType == "WindowWidget")
            return new WindowWidget<T>(Viewport, Name);
        else if (WidgetType == "ButtonWidget")
            return new ButtonWidget<T>(Viewport, Name);
        else if (WidgetType == "TextboxButtonWidget")
            return new TextboxButtonWidget<T>(Viewport, Name);
        else if (WidgetType == "TextboxWidget")
            return new TextboxWidget<T>(Viewport, Name);
        return NULL;
    }
};
And I store them in a map like this:
class WidgetFactory
{
        typedef std::map<std::string,
                         boost::function<BaseWidget*( const std::string&,
                                                      const Rect<int>&,
                                                      const std::string& )> > WidgetMapType;
        WidgetMapType WidgetMap;
        void PopulateMap()
        {
             WidgetMap["ColoredRect"]       = OneStyle<ColoredRect>();
             WidgetMap["ColoredRectBorder"] = OneStyle<ColoredRectBorder>();
             WidgetMap["RoundedRect"]       = OneStyle<RoundedRect>();
             WidgetMap["RectBorder"]        = OneStyle<RectBorder>();
             WidgetMap["GradientRect"]      = OneStyle<GradientRect>();
             WidgetMap["RoundedRectBorder"] = OneStyle<RoundedRectBorder>();
        }
};
The function PopulateMap() causes the executable to bloat with 120Kb.

Share this post


Link to post
Share on other sites
Template classes/functions can generate very large code, for example the following:

template<typename T>
void print(const T& obj)
{
std::cout << obj << std::endl;
}

int main()
{
short s = 1;
int i = 1;
char c = 1;
print(s);
print(i);
print(c);
}





Is the same as (except for some minor differences, but it will most likely be the same in release mode).

void print_s(const short& obj)
{
std::cout << obj << std::endl;
}
void print_i(const int& obj)
{
std::cout << obj << std::endl;
}
void print_c(const char& obj)
{
std::cout << obj << std::endl;
}

int main()
{
short s = 1;
int i = 1;
char c = 1;
print_s(s);
print_i(i);
print_c(c);
}




In your PopulateMap you actually create six specializations of Onestyle, so if Onestyle<T> adds 20 KB to the executable you will add 120 KB to the executable. I doubt that is the reasons for 120 KBs though, it could easily be something else.

EDIT: I can also see that Onestyle<T>::operator() creates specalizations for 4 widget types.

So by creating the populate map function you create the following classes at the same time:

OneStyle<ColoredRect>
OneStyle<ColoredRectBorder>
OneStyle<RoundedRect>
OneStyle<RectBorder>
OneStyle<GradientRect>
OneStyle<RoundedRectBorder>
WindowWidget<ColoredRect>
WindowWidget<ColoredRectBorder>
WindowWidget<RoundedRect>
WindowWidget<RectBorder>
WindowWidget<GradientRect>
WindowWidget<RoundedRectBorder>
ButtonWidget<ColoredRect>
ButtonWidget<ColoredRectBorder>
ButtonWidget<RoundedRect>
ButtonWidget<RectBorder>
ButtonWidget<GradientRect>
ButtonWidget<RoundedRectBorder>
TextboxButtonWidget<ColoredRect>
TextboxButtonWidget<ColoredRectBorder>
TextboxButtonWidget<RoundedRect>
TextboxButtonWidget<RectBorder>
TextboxButtonWidget<GradientRect>
TextboxButtonWidget<RoundedRectBorder>
TextboxWidget<ColoredRect>
TextboxWidget<ColoredRectBorder>
TextboxWidget<RoundedRect>
TextboxWidget<RectBorder>
TextboxWidget<GradientRect>
TextboxWidget<RoundedRectBorder>


If these classes are more than a few bytes this add up to many KBs. For example if the average size of these classes are 1 KB (the actual class, meaning the code) they will add 30 KBs to the executable.

[Edited by - CTar on March 25, 2006 12:52:25 PM]

Share this post


Link to post
Share on other sites
Is that a debug or a release build? When doing size comparisons, you should tell the compiler to strip all debug information, because all that information for all those template-generated classes *will* bloat the code. The information is of course a Good Thing when developing and debugging, but can usually be left out when compiling the final version.

Share this post


Link to post
Share on other sites
@CTar: Thanks a lot, I think what you said explains it nicely. It also means it was not such a good idea of me to use templates for 'dynamically' creating new types.[oh]

@Sharlin: yes, this is without debugging info and symbols are stripped.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this