使用gcc没有小的字符串优化?

时间:2017-09-06 06:45:49

标签: c++ string gcc memory optimization

大多数std::string实现(包括GCC)使用小字符串优化。例如。有一个answer在讨论这个问题。

今天,我决定检查我编译的代码中的字符串在什么时候被移动到堆中。令我惊讶的是,我的测试代码似乎表明根本没有发生小的字符串优化!

代码:

#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;
  }

}

g++ test.cc && ./a.out的输出是

capacity: 0
0x7fe405f6afb8 | 
0x7b0c38 | a
0x7b0c68 | aa
0x7b0c38 | aaa
0x7b0c38 | aaaa
0x7b0c68 | aaaaa
0x7b0c68 | aaaaaa
0x7b0c68 | aaaaaaa
0x7b0c68 | aaaaaaaa
0x7b0c98 | aaaaaaaaa
0x7b0c98 | aaaaaaaaaa
0x7b0c98 | aaaaaaaaaaa
0x7b0c98 | aaaaaaaaaaaa
0x7b0c98 | aaaaaaaaaaaaa
0x7b0c98 | aaaaaaaaaaaaaa
0x7b0c98 | aaaaaaaaaaaaaaa
0x7b0c98 | aaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
0x7b0cd8 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
0x7b0d28 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

我猜测较大的第一个指针,即0x7fe405f6afb8是堆栈指针,而其他指针指向堆。多次运行会产生相同的结果,因为第一个地址总是很大,而其他地址都比较小;确切的值通常不同。较小的地址总是遵循2分配方案的标准功率,例如, 0x7b0c38列出一次,然后列出0x7b0c68一次,然后0x7b0c38两次,然后0x7b0c68 4次,然后0x7b0c98 8次,等等。

在阅读霍华德的答案后,使用64位机器,我希望看到前22个字符打印的地址相同,然后才能看到它的变化。

我错过了什么吗?

另外,有趣的是,如果我使用-O(在任何级别)进行编译,我会在第一种情况下得到一个常量小指针值0x6021f8,而不是大值,而{{1}无论我运行程序多少次都不会改变。

0x6021f8的输出:

g++ -v

1 个答案:

答案 0 :(得分:18)

你的一面旗帜是:

--with-default-libstdcxx-abi=gcc4-compatible

并且GCC4 支持小字符串优化。

GCC5开始支持它。 isocpp州:

  

默认情况下,使用小字符串优化而不是写入时复制引用计数来启用std :: string的新实现。

支持我的主张。

此外,Exploring std::string提及:

  

正如我们所看到的,旧的libstdc ++实现了写时复制,因此它实现了   感觉他们不利用小物件优化。

然后他改变了背景,当GCC5进场时。