现在的位置: 首页 > 综合 > 正文

作为局部变量的std::string和标准库容器一种内存优化方法

2013年12月10日 ⁄ 综合 ⁄ 共 1117字 ⁄ 字号 评论关闭

实际项目中,往往看到好多项目把std::string, std::vector作为局部变量直接使用的情况。 类似下面std::string的用法:

void SomeClass::Fun()
{
        std::string str = "abcd";
        str += "efgh";
}
        

下面是std::vector的类似例子:

void SomeClass::Fun2()
{
        std::vector<int> iv;
        iv.push_back(22);
        
        DoFun2(iv);
}
       

在后台服务器出现上面类似的代码最好还是优化一下。上面代码涉及堆内存的申请和释放,运行频繁的话,会产生碎片。

一种优化方法是,把std::string作为SomeClass的成员变量:

class SomeClass
{
private:
      std::string m_str;
};

void SomeClass::Fun()
{
        m_str.clear();      // 每次用的时候,清一下
        m_str = "abcd";
        m_str += "efgh";
}

std::string的特点是clear()的时候,只清内容,不释放内存。std::vector也有这类特点,也可用类似的方法。

还有一类容器,比如std::list, std::map, xxx::hash_map等, clear()的时候,同时也会释放内存,这个也好办,传一个allocator给他。下面用 std::list举例,std::string麻烦一点, 得用std::basic_string.

class SomeClass
{
private:
      std::list<int, __gnu_cxx::pool_alloc<int> > m_list;
};

这样调用m_list.clear()的时候,内存的释放从pool_alloc释放。避免了从堆中分配和释放了。

上面一种方法如果SomeClass的对象生命周期结束了,allocator中的内存还是会释放。我们可以考虑第二种方法,引入一个全局性质的allocator,只要类型一样的局部容器都可以用。这样类对象的生命周期结束了,也不会引起内存释放。

YourAllocator<int> g_intAllocator;

void SomeClass::Fun()
{
     std::vector<int, YourAllocator<int> > v(g_intAllocator);
     UseV(v);
}

YourAllocator,Linux上可以用__gnu_cxx::pool_alloc.   其他需要int的局部容器变量,可以共用这个g_intAllocator。这样内存的申请和分配都在g_intAllocator内部进行,都是O(1),内存也很紧凑,保证高效。

抱歉!评论已关闭.