대부분의 std::string
구현 (GCC 포함)은 작은 문자열 최적화를 사용합니다. 예 : 이에 대한 설명은 answer입니다.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;
}
}
g++ test.cc && ./a.out
의 출력은 내가 더 큰 첫 번째 포인터, 즉 0x7fe405f6afb8
는 스택 포인터라고 추측하고있어, 다른 사람이 힙을 가리
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
입니다 . 이것을 여러 번 실행하면 첫 번째 주소는 항상 크고 다른 주소는 더 작다는 의미에서 동일한 결과가 산출됩니다. 정확한 값은 보통 다릅니다. 더 작은 주소는 항상 2 할당 방식의 표준 능력을 따른다. 0x7b0c38
, 하워드의 답변을 읽는 64 비트 기계를 사용한 후 다음 두 번 다음, 다음 0x7b0c68
번 목록에 한 번 다음 0x7b0c68
4 회, 0x7b0c98
8 배, 등을 0x7b0c38
을 나열, 나는 같은 주소가 인쇄보기 위해 기다리고 있었다 처음 22 자 동안, 그리고 그때 만 바뀌어 보입니다.
내가 누락 된 항목이 있습니까? 내가 (모든 수준에서) -O
로 컴파일하는 경우
또한, 흥미롭게도, 내가 대신 큰 가치, 첫 번째 경우에 일정한 작은 포인터 값 0x6021f8
를 얻을 얼마나 많은 시간이 0x6021f8
는 관계없이 변경되지 않습니다 나는 프로그램을 운영한다. g++ -v
의
출력 : 당신의 플래그의
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/foo/bar/gcc-6.2.0/gcc/libexec/gcc/x86_64-redhat-linux/6.2.0/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../gcc-6.2.0/configure --prefix=/foo/bar/gcc-6.2.0/gcc --build=x86_64-redhat-linux --disable-multilib --enable-languages=c,c++,fortran --with-default-libstdcxx-abi=gcc4-compatible --enable-bootstrap --enable-threads=posix --with-long-double-128 --enable-long-long --enable-lto --enable-__cxa_atexit --enable-gnu-unique-object --with-system-zlib --enable-gold
Thread model: posix
gcc version 6.2.0 (GCC)
'--with-default-libstdcxx-abi = gcc4-compatible' –
@ T.C. 정말? 'gcc4'에는 작은 문자열 최적화가 없었습니다? – SU3
작은 문자열 최적화가 언어에 포함되어야한다는 것을 기억했습니다. – xaxxon