【发布时间】:2015-02-05 15:13:25
【问题描述】:
我有一个函数,它从带有两个数字的const char* 构造一个std::string,作为参数传递,附加到它的末尾。
std::string makeName(const char* name, uint16_t num1, uint16_t num2) {
std::string new_name(name);
new_name.reserve(new_name.length()+5);
new_name += ":";
new_name += boost::lexical_cast<std::string>(num1);
new_name += ":";
new_name += boost::lexical_cast<std::string>(num2);
return new_name;
}
这个函数被调用数千次,为分配在堆上的小对象创建唯一的名称。
Object* object1= new Object(makeName("Object", i, j)); // i and j are simply loop indices
我发现使用 valgrind 的 massif 工具调用 makeName 会分配大量内存,因为它被调用了很多次。
87.96% (1,628,746,377B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->29.61% (548,226,178B) 0xAE383B7: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
| ->26.39% (488,635,166B) 0xAE38F79: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
| | ->26.39% (488,633,246B) 0xAE39012: std::string::reserve(unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
| | | ->15.51% (287,292,096B) 0x119A80FD: makeName(char const*, unsigned short, unsigned short) (Object.cpp:110)
| | | | ->15.51% (287,292,096B) in 42 places, all below massif's threshold (01.00%)
我的问题是,如何最大限度地减少这些分配以帮助减少程序使用的总内存量?
编辑: 我还想指出,作为程序要求,我不能使用 c++11 功能。
【问题讨论】:
-
尝试使用字符串流。
sstream ss; ss << name << " : " << num1 << " : " << num2; return ss.str(); -
“名称”必须是
std::string吗?如果您的对象数量在数字限制范围内,如何为其分配一个唯一的int? -
@NathanOliver 很好的第一步:但如果有问题的代码是一个严重的瓶颈,那么转到
stringstream不是答案。 -
@akashPradhan - 这是一个很好的建议,但是对象的名称通常不是“对象”——它将是对象的描述性名称
-
哦,我们在谈论多少个对象?名称
"Object:22:979"将占用 14 字节的内存,加上 12-24 字节用于跟踪它的指针,以及另外 4-16 字节的堆分配开销。如果这与您的对象相比很大,并且您有很多对象......那就是开销。如果对象很小,那么高百分比可能是因为这是您要求的?
标签: c++ valgrind allocation stdstring