2014-11-04 4 views
6

나는 같은 간단한 코드 시도 :왜 컴파일러는 std :: string concat를 최적화 할 수 없습니까?

int main() 
{ 
    puts("ab"); 
    return 0; 
} 

에 같은 코드를 최적화 내가 그 컴파일러를 기대

#include <cstdio> 
#include <string> 

int main() 
{ 
    const std::string s = std::string("a") + "b"; 
    puts(s.c_str()); 
    return 0; 
} 

(GCC 4.8.2/연타 3.5.0)를하지만 같은 결과를 얻을 수 없습니다, I "-Ofast", "-flto", "-static-된 libstdC++"와 같은 다른 옵션을하려고 노력하지만, 항상 세 가지 기능 전화 디스어셈블러 출력에 참조 :

... 
callq 0x4017e0 <_ZNSsC2EPKcRKSaIcE> 
... 
callq 0x401690 <_ZNSs6appendEPKc> 
... 
callq 0x401490 <_ZNSs4_Rep10_M_disposeERKSaIcE> 

첫 번째는 성병 전화 :: basic_string입니다, std :: allocator :: basic_string (char const *, std :: allocator const &).

주위에있는 모든 컴파일러가 있으므로 puts ("ab")와 같은 코드를 최적화 할 수 있습니다. 또는 적어도 "std :: string s ("ab ");"?

그런 컴파일러가없는 경우 구현하기가 어려운 최적화 방법은 무엇입니까?

업데이트 실제 사용법. 내가/표시 등 패턴 실제 코드 곳곳 보았다

std::string s = std::string(string_const1) + string_const2 + string_variable + string_const3; 

을 그리고 성능이 중요한 경우, 물론 더 최적의 방법으로 같은 코드를 다시 작성하는 것이 가능하다.

그러나 현대 컴파일러는 코드를 최적화하는 데 큰 도움이됩니다. 그리고 gcc는 malloc/free/strcpy/strcat 등을위한 __builtin 함수를 가지고 있습니다. 그리고 gcc의 libstdC++에서 std :: basic_string이이 함수 (malloc, free, strcpy, strcat)를 구현의 일부로 사용한다면 함수 사용법의 결과를 예측하고 대답을 내리지 않는 것이 좋습니다.

+0

C++ 클래스 생성자와 연산자는 함수이기 때문에 대수적이지 않으므로 대수적 최적화를 탐지하기가 어렵습니다. – didierc

+1

왜 이렇게하고 싶지는 않지만 'const std :: string s = "a" "b";' 당신의 필요에 맞게? 문자열 리터럴은 서로 옆에 쓰면 자동 붙여 넣기됩니다. –

+0

C++ 표준은 프로그램이'puts ("ab"); 또는 동등한 것으로 최적화되도록 허용한다. 그러나 컴파일러는 그것을하지 않습니다. 아마 컴파일러 개발자에게 물어보아야 할 것 같지만, 프로그래머의 희망을 존중하는 것과 관련이 있습니다. 궁극적으로 * if-if * 규칙을 따랐다면 많은 불만이있을 것입니다. 예 : 화면에 무엇인가를 쓰거나 잠을 자도록 시스템 콜을하는 것은 C++ 14의 정의에 따라 관찰 가능한 행동을 취하지 않는다. –

답변

7

std::string은 저장소의 동적 할당과 대부분의 경우 매우 복잡한 구현을 포함하므로 컴파일러가 파인 아트에 얼마나 지속적으로 폴딩하는지에 관계없이 컴파일 타임 의미로 축소 할 수 없습니다.

그러나 string이 실제로 다음과 같이 선언 된 경우 왜 char 배열을 먼저 사용하지만 string을 선택하지 않았습니까? 다른 문자열을 생성하기 위해 일부 문자열을 사용해야하는 경우 char 배열로 작업 할 수있는 도구가 여전히 있습니다. 특히 C++ 11에 가변적 인 템플릿과 constexpr이 도입 된 이후입니다. C++의 향후 버전은 희망 사항으로 std::string_literal을 추가하여 더 쉽게 사용할 수 있습니다.

+0

C++ 14 기능을 사용하여 constexpr std :: string :: operator +을 사용하고 OP의 요청을 구현할 수 있습니까? – liori

+0

@liori 'string_literal'은 C++ 14를 기반으로하므로 생각해야합니다. – Columbo

+1

또한 GCC의'std :: string'은 여전히 ​​copy-on-write라는 복잡한 문제가 있습니다. –