在关于优化和代码风格的C++问题中,在优化副本的上下文中,有几个答案提到了"SSO" std::string.在这种情况下,SSO意味着什么?
显然不是"单点登录"."共享字符串优化",或许?
我有一个简单的问题.我想知道std::string每次在C++中是否分配内存.
在我的代码中,似乎构造函数将使用更多的内存来构造而tst_first_string不是tst_second_string:
char* first_string = new char[5];
strcpy(first_string, "test");
std::string tst_first_string(first_string);
std::string tst_second_string("test");
Run Code Online (Sandbox Code Playgroud) 所以这里有一个小测试程序:
#include <string>
#include <iostream>
#include <memory>
#include <vector>
class Test
{
public:
Test(const std::vector<int>& a_, const std::string& b_)
: a(std::move(a_)),
b(std::move(b_)),
vBufAddr(reinterpret_cast<long long>(a.data())),
sBufAddr(reinterpret_cast<long long>(b.data()))
{}
Test(Test&& mv)
: a(std::move(mv.a)),
b(std::move(mv.b)),
vBufAddr(reinterpret_cast<long long>(a.data())),
sBufAddr(reinterpret_cast<long long>(b.data()))
{}
bool operator==(const Test& cmp)
{
if (vBufAddr != cmp.vBufAddr) {
std::cout << "Vector buffers differ: " << std::endl
<< "Ours: " << std::hex << vBufAddr << std::endl
<< "Theirs: " << cmp.vBufAddr << std::endl;
return false;
}
if (sBufAddr != cmp.sBufAddr) {
std::cout …Run Code Online (Sandbox Code Playgroud) 考虑以下测试程序:
#include <iostream>
#include <string>
#include <vector>
int main()
{
std::cout << sizeof(std::string("hi")) << " ";
std::string a[10];
std::cout << sizeof(a) << " ";
std::vector<std::string> v(10);
std::cout << sizeof(v) + sizeof(std::string) * v.capacity() << "\n";
}
Run Code Online (Sandbox Code Playgroud)
输出libstdc++和libc++分别是:
8 80 104
24 240 264
Run Code Online (Sandbox Code Playgroud)
如您所见,libc++对于一个简单的程序,需要3倍的内存.实现有何不同会导致这种内存差异?我需要关注,我该如何解决它?
我浏览了虚幻引擎源代码,发现它们使用自己的容器类,例如内部动态数组。但是 C++ STL 提供了(几乎)所有必需的容器类。那么他们为什么要花时间再次开发相同的容器呢?对于开发人员来说,使用容器std::vector来编写他们的代码而不是试图弄清楚如何使用TArray引擎中的类来做事情不是更容易吗?
大多数std::string实现(包括GCC)使用小字符串优化.例如,有一个答案在讨论这个问题.
今天,我决定检查我编译的代码中的字符串在什么时候被移动到堆中.令我惊讶的是,我的测试代码似乎表明根本没有发生小的字符串优化!
码:
#include <iostream>
#include <string>
using std::cout;
using std::endl;
int main(int argc, char* argv[]) {
std::string s;
cout << "capacity: " << s.capacity() << endl;
cout << (void*)s.c_str() << " | " << s << endl;
for (int i=0; i<33; ++i) {
s += 'a';
cout << (void*)s.c_str() << " | " << s << endl;
}
}
Run Code Online (Sandbox Code Playgroud)
输出g++ test.cc && ./a.out是
capacity: 0
0x7fe405f6afb8 |
0x7b0c38 | a
0x7b0c68 | aa …Run Code Online (Sandbox Code Playgroud) 今天我下载并创建了一个Electronic Arts STL实现的示例项目,EA的矢量看起来比标准慢得多.我刚创建了2个向量并上传了100万个项目:
void performance_test(void)
{
clock_t start;
clock_t end;
// EA
eastl::string strEA = "hello";
eastl::vector<eastl::string> vec_EA;
start = clock();
for (size_t i = 0; i < 1000000; i++)
{
vec_EA.push_back(strEA);
}
end = clock();
printf("EA %f\n", (double(end - start) / 1000));
// Standard
std::string strStandard = "hello";
std::vector<std::string> vec_Standard;
start = clock();
for (size_t i = 0; i < 1000000; i++)
{
vec_Standard.push_back(strStandard);
}
end = clock();
printf("Standard %f\n", (double(end - start) / 1000));
}
Run Code Online (Sandbox Code Playgroud)
结果是:
我有以下C++代码:
#include <string>
#include <iostream>
int main(int argc, char** argv)
{
int size;
std::string strArray[3];
std::string str0 = "String 0";
std::string str1 = "String 1";
std::string str2 = "String 2";
strArray[0] = str0;
strArray[1] = str1;
strArray[2] = str2;
for (int i = 0; i < 3; i++)
{
std::cout << strArray[i] << std::endl;
}
str1.resize(200, 'a');
for (int i = 0; i < 3; i++)
{
std::cout << strArray[i] << std::endl;
}
std::cout << str1 << std::endl;
std::cin.get();
return …Run Code Online (Sandbox Code Playgroud) 将字符串视为字符向量似乎是显而易见的.那么为什么字符串有自己的特殊实现,这似乎与矢量类有很大的不同?
为了说明这一点,这里有两个类的一些片段,表明所需的工作非常相似,例如使用分配器来管理内存.同样具有特征也可用于载体.
如果我们允许向量具有类型特征,那么从std :: string的实现中剪切下来看起来它将适合std :: vector的更一般的实现.
139 template <class _charT, class _Traits , class _Allocator > |
140 class _RWSTDExportTemplate basic_string |
141 { |
142 public:
....
333 size_type size () const { return length(); } |
334 inline size_type length () const; |
335 size_type max_size () const |
336 { |
337 return npos - sizeof(__rep_type)-2; |
338 } |
339 inline void resize (size_type, _charT); |
340 void resize (size_type n) |
341 { | …Run Code Online (Sandbox Code Playgroud)