我目前正在开发一个低内存平台的应用程序,该平台需要std :: set的许多短字符串(> 100,000个字符串,每个字符串4-16个字符)。我最近将这个集合从std :: string转换为const char *以节省内存,我想知道我是否真的避免了每个字符串的所有开销。
我尝试使用以下内容:
std::string sizeTest = "testString";
std::cout << sizeof(sizeTest) << " bytes";
但它只给了我一个4字节的输出,表明该字符串包含一个指针。我很清楚字符串在内部将它们的数据存储在char *中,但我认为字符串类会有额外的开销。
std :: string的GCC实现是否会产生比sizeof(std :: string)更多的开销?更重要的是,这个数据集的大小是否显着?
以下是我平台上相关类型的大小(它是32位,每字节8位):
char:1个字节
void *:4个字节
char *:4个字节
std :: string:4个字节
答案 0 :(得分:13)
好吧,至少GCC 4.4.5,这就是我对此有用的东西
机器,std::string
是std::basic_string<char>
的典型代码,并且
basic_string
定义于
/usr/include/c++/4.4.5/bits/basic_string.h
。有很多
在该文件中的间接,但它归结为非空
std::string
存储指向其中一个的指针:
struct _Rep_base
{
size_type _M_length;
size_type _M_capacity;
_Atomic_word _M_refcount;
};
通过实际的字符串数据跟踪内存。所以std::string
是
每个字符串至少要有三个字句,加上
比capacity
更高`length
的任何开销(可能是。{
不是,取决于你如何构建你的字符串 - 你可以检查
询问capacity()
方法。
你的内存分配器也会产生开销
很多小额拨款;我不知道GCC用于C ++的是什么,但是
假设它类似于它用于C的dlmalloc
分配器,那
可以是每个分配至少两个单词,加上一些空格来对齐
大小为至少8个字节的倍数。
答案 1 :(得分:8)
我猜你是在32位,每字节8位平台上。我还要猜测,至少在您使用的gcc版本上,他们正在使用std :: string的引用计数实现。您看到的4字节大小是指向包含引用计数和字符串数据(以及任何分配器状态,如果适用)的结构的指针。
在gcc的这种设计中,唯一的“短”字符串的大小为== 0,在这种情况下,它可以与每个其他空字符串共享一个表示。否则你会得到一个refcounted COW字符串。
要自己调查一下,编写一个分配器来跟踪它分配和释放的内存量,以及多少次。使用此分配器来调查您感兴趣的容器的实现。
答案 2 :(得分:3)
如果保证“&gt; 100,000个字符串,每个字符串4-16个字符”,则不要使用std :: string。相反,编写自己的ShortString类。有趣的是“sizeof(std :: string)== 4”,这怎么可能?什么是sizeof(char)和sizeof(void *)?
答案 3 :(得分:2)
我已经对std :: string开销进行了一些比较。一般来说它大约是48个字节!看看我博客上的文章: http://jovislab.com/blog/?p=76