2012-01-18 3 views
10
나는 현재는 "C++ 프로그래밍 언어 : 스페셜 에디션"에 읽고 있어요

지연의 즉시 값으로 문자열을 정의 할 때 : 들어하기 권장 속도 향상 대신

비얀 스트로브 스트 룹에 의해 및 133 페이지를 다음과 같은 상태 사용자 정의 형식을 사용하면 까지 변수 정의를 연기하면 적합한 이니셜 라이저를 사용할 수 있으므로 성능이 향상 될 수 있습니다. 예를 들어 :

string s; /* .... */ s = "The best is the enemy of the good."; 

쉽게 나는 그것이 필요하지만 그냥 말을하자, 그렇게되지 않습니다 의미가 쉽게를 말합니다 알고

string s = "Voltaire"; 

보다 훨씬 속도가 느려질 수 있습니다 그것은 발생합니다.

의 잠재 수치가으로 증가할까요?

사용자 정의 유형 (또는 STL 유형)에만 해당합니까? int, float 등과 같은 경우에도 해당합니까?

+0

아래의 답변 외에도 도움이 될 수 있습니다. http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.22 – dsign

답변

9

필자는 이것이 적어도 성능면에서 중요하지 않은 기본 생성자가있는 유형에 관한 것이라고 말하고 싶습니다.

두 방법의 차이는 점이다

최초 버전의
  • 가 빈 문자열 제 (기본 생성자를 사용)로 구성되고; 대입 연산자는 기본 생성자가 수행 한 작업을 효과적으로 버리고 새로운 값을 문자열에 할당하는 데 사용됩니다.
  • 두 번째 버전에서는 필요한 값이 즉시 생성됩니다.

물론 이것은 성능 차이가 얼마나 큰지를 선험적으로 말하기 어렵습니다.

+0

성능 차이는 사용자가 정의한 유형에서 특히 두드러집니다. POD 유형에는 거의 없습니다. –

7
  1. 그것은 기본 생성자을 실행 에 시간이 걸립니다. 이후에 문자열을 초기화 한 것을 무시하면 호출 된 할당 연산자도 걸립니다.

  2. 기본 생성자 호출과 할당 연산자 사이에 함수가 (return 문 또는 예외로 인해)있을 때 실행이 할당에 도달하지 않을 수 있습니다. 이 경우 객체는 이 기본값으로 불필요하게으로 초기화되었습니다.

  3. 구현은 예외가 발생하는 경우 개체의 소멸자라고 확인하기 위해 성능을 낭비 할 수 있습니다. 객체가 결코 도달하지 않은 후속 범위에서 초기화되는 경우에도 필요하지 않습니다.

+1

범위의 문제는 여기에서 가장 중요하다고 생각하며, 다른 모든 대답은이 문제에서 벗어났습니다. Stroustrup에서 분명하지 않은 점은 후자의 경우 변수를 모두 사용하지 않는 것입니다. –

1

때문에 :

string s; /* .... */ s = "The best is the enemy of the good.";  

이 두 가지 작업이 포함됩니다 건설 및 할당을

동안 :

string s = "Voltaire"; 

단지 건설을 포함한다.

Member Initializer lists over Assignment in Constructor body을 선택하는 것과 같습니다.

string s;   // Default constructor 
string s = "..."; // Default constructor followed by operator assignment 
string s("..."); // Constructor with parameters passed in 

문자열 클래스는 메모리를 할당 할 필요가 :

-1

클래스는 문자열을 초기화하는 방법은 세 가지가 있습니다. 필요한 메모리 양을 알고 나면 할당하는 것이 좋습니다.

+2

두 번째 경우는 복사 초기화이며 기본 생성자 또는 할당 연산자를 절대로 사용하지 않습니다. 이것은 기술적으로 임시 변환 캐터를 만들고 나서's '의 복사본을 생성하지만 대개 불필요한 복사본은 생략되어 직접 초기화 (사례 3)와 동일합니다. –

0

좋은 질문입니다. 맞습니다. 복잡한 유형에서만 발생합니다. 나는. 클래스 및 구조체, std :: string 같은 개체입니다. 여기에 관련된 실제 문제는 생성자와 관련이 있습니다.

객체가 생성

, 즉 그것의 생성자를 호출

std::string s; 

, 아마, 일부 메모리를 할당 다른 변수 초기화를 수행 자체를 사용할 준비가 가져옵니다. 사실, 많은 양의 코드가 코드의이 시점에서 실행될 수 있습니다. 나중에에

는 수행

s = "hello world!"; 

이 그것을 짓을의 대부분을 버리고, 그것을 새로운 문자열 내용입니다 교체 할 준비를해야 할 클래스를 야기한다. 당신이 변수가 정의 된 값을 설정하면

실제로 단일 작업으로 감소, 즉 : 디버거의 코드를 보면,

std::string s = "Hello world"; 

사실, 한 번 다른 생성자를 실행합니다 개체를 구성한 다음 별도로 값을 설정하는 대신 실제로 이전 코드는 다음과 같이 동일하게 작동합니다.

std::string s("Hello world"); 

조금만 정리하면 도움이 되었기를 바랍니다.

+1

사실, 좋은 구현의'string' 디폴트 생성자는 반드시 메모리를 반드시 할당 할 필요는 없습니다. 나는 gcc의'vector'가 확실하지 않다는 것을 안다. –

+1

문자열의 이전 상태를 처리 및/또는 재사용하는 것을 고려해야하기 때문에 실제 비용은 할당이 구조보다 복잡하다는 사실 일 가능성이 높습니다. 생성자는 이전 상태가 없음을 알고 있습니다. –

0

두 경우 모두 어떤 일이 발생하는지 고려하십시오.첫 번째 경우 "의"

  • 할당 연산자 "S"
  • 두 번째 경우에 대해 호출을 요구

    • 기본 생성자 먼저이 string s("Voltaire")에 해당 복사 생략과 그 고려 따라서 :

      • 는 C 문자열 생성자가 호출

      논리적으로 첫 번째 접근 방식은 추상 기계가 더 많은 작업을 수행해야합니다. 실제로이 코드가 실제 코드로 변환되는지 여부는 실제 유형과 최적화 프로그램이 수행 할 수있는 정도에 따라 다릅니다. 모든 사소한 사용자 유형의 경우 옵티마이 저는 기본 생성자가 부작용이 있다고 가정해야 할 수도 있으므로 단순히 제거 할 수는 없습니다.

      이 추가 비용은 비용이 기본 생성자에 있으므로 사용자 유형에만 적용됩니다. int와 같은 임의의 기본 유형 또는 사실 단순한 생성자/복사가있는 경우에는 기본 생성자에 대한 비용이 들지 않습니다. 데이터는 단순히 초기화되지 않습니다 (함수 범위에서).

    0

    왜 잠재적 인 성능 향상이 발생합니까?

    첫 번째 경우에는 기본 초기화와 할당이 이어집니다. 두 번째는 값에서 초기화를 포함합니다. 기본 초기화는 나중에 할당 (또는 실행 취소)해야하는 작업을 수행 할 수 있으므로 첫 번째 경우는 두 번째 작업보다 많은 작업이 필요할 수 있습니다.

    사용자 정의 유형 (또는 STL 유형) 만있는가요? 또는 int, float 등의 경우에도 해당합니까?

    사용자 정의 유형에만 해당됩니다. 그리고 생성자와 대입 연산자가 실제로하는 일에 달려 있습니다. 스칼라 유형의 경우 기본 초기화는 아무 작업도 수행하지 않으며 할당은 값의 초기화와 동일한 작업을 수행하므로 두 가지 옵션이 동일합니다.