通过包装容器减少STL代码膨胀 [英] Reducing STL code bloat by wrapping containers

查看:191
本文介绍了通过包装容器减少STL代码膨胀的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个C ++库(超过50个源文件),它使用很多STL例程,主容器是list和vector。这导致了巨大的代码膨胀,我想通过在列表和向量上创建一个包装来减少代码膨胀。



下面是我的包装器std ::和包装的实例。

  template< typename T& 
class wlist
{
private:
std :: list< T> m_list;

public:

//新迭代器集。
typedef typename std :: list< T> :: iterator iterator;
typedef typename std :: list< T> :: const_iterator cIterator;
typedef typename std :: list< T> :: reverse_iterator reverse_iterator;

unsigned int size(){return m_list.size(); }
bool empty(){return m_list.empty(); }
void pop_back(){m_list.pop_back(); }
void pop_front(){m_list.pop_front(); }
void push_front(T& item){m_list.push_front(item); }
void push_back(T item){m_list.push_back(item); }
迭代器插入(迭代器位置,T项){m_list.insert(position,item);}
bool delete_item(T& item);
T back(){return(m_list.empty())? NULL:m_list.back();}
T front(){return(m_list.empty())? NULL:m_list.front();}
迭代器擦除(迭代器项){return m_list.erase(item); }
iterator begin(){return m_list.begin(); }
iterator end(){return m_list.end(); }
reverse_iterator rbegin(){return m_list.rbegin(); }
};

档案A:

  class label {

public:

int getPosition(void);
setPosition(int x);

private:

wlist< text *> _elementText; // used in place of list< text> _elementText;

}

档案B:

  class image {

private:

void draw image(){
wlist& > :: iterator currentElement = _elementText.begin();
((label *)(* currentElement)) - > getPosition();
currentElement ++;
}
}



我认为通过包装STL容器将能够减少代码膨胀,但代码大小的减少似乎是微不足道,而我的动机包装STL是实现约20%的代码减少。



1)通过暴露包装迭代器,我转而嵌入STL到我的客户端代码,从而否定所有的代码保存,我试图做?
2)我选择了正确的分析方法吗?



修改前的大小:

  $ size libWrap.so 

text:813115
data:99436
bss:132704
dec:1045255
hex:ff307

修改后的大小:

  $ size libWrap.so 

text:806607
data:98780
bss:132704
dec:1038091
hex:fd70b


解决方案

你的包装是完全和完全恶心的。有一个原因,迭代器存在,这是因为你的实现展开不适用于非指针类型。按值返回和采用而不是参考?一个可怕的设计。



其次,您可以通过引入更多代码从不减少程序的大小。你的包装器仍然使用STL列表,所以你仍然实例化所有这些类型。很可能,编译器只是完全删除了所有的内容。



第三,你甚至没有做一个等价替换,因为你已经替换了以前是一个列表的价值观列表的指针,引入六百万生活头痛和其他问题。



第四,即使代码膨胀的想法在绝大多数平台是相当可笑的。我,当然,不能精神上知道你不是在一些嵌入式平台上几乎没有任何内存(虽然我怀疑你会使用这样的平台上的许多列表),但在几乎每个系统,代码本身的大小比较无意义

您可以做的是尝试类似于SCARY迭代器或T *的部分专门化。

/ p>

I have a C++ library (with over 50 source files) which uses a lot of STL routines with primary containers being list and vector. This has caused a huge code bloat and I would like to reduce the code bloat by creating a wrapper over the list and vector.

Shown below is my wrapper over std:: and the wrapped instances.

template<typename T>
class wlist
{
private:
    std::list<T> m_list;

public:

    // new iterator set.
    typedef typename std::list<T>::iterator iterator;
    typedef typename std::list<T>::const_iterator cIterator;
    typedef typename std::list<T>::reverse_iterator reverse_iterator;

    unsigned int size () { return m_list.size(); }
    bool empty () { return m_list.empty(); }
    void pop_back () { m_list.pop_back(); }
    void pop_front () { m_list.pop_front(); }
    void push_front (T& item) { m_list.push_front(item); }
    void push_back (T item) { m_list.push_back(item); }
    iterator insert(iterator position, T item) {m_list.insert(position,item);}
    bool delete_item (T& item);
    T back () { return (m_list.empty()) ? NULL : m_list.back();}
    T front () { return (m_list.empty()) ? NULL : m_list.front();}
    iterator erase(iterator item ) { return m_list.erase(item); }
    iterator begin() { return  m_list.begin(); }
    iterator end() { return m_list.end(); }
    reverse_iterator rbegin() { return  m_list.rbegin(); }
};

File A:

class label {

public:

int getPosition(void);
setPosition(int x);

private:

wlist<text*> _elementText; // used in place of list<text> _elementText;

}

File B:

class image {

private:

    void draw image() {
        wlist<label*>::iterator currentElement = _elementText.begin();
       ((label*)(*currentElement))->getPosition();    
        currentElement ++;
    }
}

My belief was that by wrapping the STL container, I would be able to reduce the code bloat but the reduction in code size seems to be insignificant while my motive to wrap the STL was to achieve a code reduction of roughly 20%.

1) By exposing the "wrapped" iterator, have I in-turn embedded STL into my client code thereby negating all the code saving that I was trying to do ???? 2) Have I chosen the right profiling method ????

Size before modification:

$ size libWrap.so

text:  813115
data: 99436
bss:  132704
dec : 1045255
hex:  ff307     

Size after modification:

$ size libWrap.so

text:  806607
data: 98780
bss:  132704
dec : 1038091
hex:  fd70b

解决方案

Firstly, the interface offered by your wrapper is completely and totally disgusting. There's a reason that iterators exist, and it's because your implementation flat out doesn't work for non-pointer types. Returning and taking by value instead of by reference? A terrible design.

Secondly, you can never reduce the size of your program by introducing more code. Your wrapper still uses the STL list under the hood, so you're still instantiating all of those types. Most likely, the compiler just completely removed the whole lot.

Thirdly, you're not even doing an equivalent replacement, because you've replaced what used to be a list of values wth a list of pointers, introducing six million lifetime headaches and other problems.

Fourthly, even the idea of code bloat is quite ridiculous on the vast majority of platforms. I, of course, cannot psychically know that you are not working on some embedded platform with hardly any memory (although I doubt you would use many lists on such a platform) but on virtually every system, the size of the code itself is meaningless compared to other assets needed for the program to execute.

What you can do is try something like SCARY iterators or partial specializations for T*.

这篇关于通过包装容器减少STL代码膨胀的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆