std :: strings를 반환해야합니까?
가능할 때마다 std::string대신 사용하려고 char*하지만 성능이 너무 저하 될 수 있습니다. 이것은 문자열을 반환하는 좋은 방법입니까 (간결성을 위해 오류를 확인하지 않음)?
std::string linux_settings_provider::get_home_folder() {
return std::string(getenv("HOME"));
}
또한 관련 질문 : 문자열을 매개 변수로 허용 할 때 const std::string&또는 로 수신해야 const char*합니까?
감사.
문자열을 반환합니다.
더 나은 추상화가 그만한 가치가 있다고 생각합니다. 의미있는 성능 차이를 측정 할 수있을 때까지 상상 속에서만 존재하는 마이크로 최적화라고 생각합니다.
좋은 문자열 추상화를 C ++로 가져 오는 데 수년이 걸렸습니다. 나는 그의 보수적 인 "사용한만큼만 지불한다"라는 말로 유명한 Bjarne Stroustroup이 명백한 성능 킬러를 언어로 허용했을 것이라고 믿지 않습니다. 더 높은 추상화가 좋습니다.
모두가 말한 것처럼 문자열을 반환하십시오.
문자열을 매개 변수로 허용 할 때 const std::string&또는 로 수신해야 const char*합니까?
값으로 취할 수있을만큼 가볍지 않은 경우 또는 "위의 사항 중 하나도"를 의미하는 유효한 입력이되기 위해 널 포인터가 필요한 드문 경우가 아니면 const 매개 변수를 참조로 사용한다고 말하고 싶습니다. 이 정책은 문자열에만 국한되지 않습니다.
상수가 아닌 참조 매개 변수는 논란의 여지가 있습니다. 호출 코드 (좋은 IDE가없는 경우)에서 값으로 전달되는지 참조로 전달되는지 즉시 확인할 수없고 그 차이가 중요하기 때문입니다. 따라서 코드가 명확하지 않을 수 있습니다. const 매개 변수의 경우 적용되지 않습니다. 호출 코드를 읽는 사람들은 일반적으로 문제가 아니라고 가정 할 수 있으므로 때때로 서명을 확인하면됩니다.
함수에서 인수의 사본을 가져 오려는 경우 일반적인 정책은 인수를 값으로 취하는 것입니다. 그런 다음 이미 사용할 수있는 복사본이 있고 데이터 멤버와 같은 특정 위치에 복사 한 경우이를 이동 (C ++ 11)하거나 스왑 (C ++ 03) 할 수 있습니다. 거기로가. 이를 통해 컴파일러는 호출자가 임시 개체를 전달하는 경우를 최적화 할 수 있습니다.
의 경우 string특히,이 커버 함수가 걸리는 경우 std::string값으로, 인수 식 문자열 리터럴 또는 같은 발신자 지정 char*널로 끝나는 문자열을 가리키는. a를 가져 와서 const std::string&함수에 복사하면 두 개의 문자열이 생성됩니다.
값별로 문자열을 복사하는 비용은 작업중인 STL 구현에 따라 다릅니다.
MSVC의 std :: string은 짧은 문자열 최적화를 사용하므로 짧은 문자열 (<16 자 iirc)에는 메모리 할당이 필요하지 않으며 (std :: string 자체에 저장 됨), 긴 문자열에는 힙 할당이 필요합니다. 문자열이 복사 될 때마다.
GCC의 std :: string은 참조 카운트 구현을 사용합니다. char *에서 std :: string을 구성 할 때 매번 힙 할당이 수행되지만 값을 함수에 전달할 때 참조 카운트가 단순히 증가하여 메모리 할당.
일반적으로 초당 수천 번 수행하지 않는 한 위의 내용을 잊어 버리고 값으로 std :: strings를 반환하는 것이 좋습니다.
re : 매개 변수 전달, char *-> std :: string에서 비용이 발생하지만 std :: string-> char *에서 발생하는 비용이 없음을 명심하십시오. 일반적으로 이것은 std :: string에 대한 const 참조를 받아들이는 것이 더 낫다는 것을 의미합니다. 그러나 const std :: string &을 인수로 받아들이는 가장 좋은 이유는 피 호출자가 null 대 검사를위한 추가 코드를 가질 필요가 없다는 것입니다.
좋은 생각 같네요.
이것이 게임과 같은 실시간 소프트웨어의 일부가 아니라 일반 응용 프로그램이라면 괜찮습니다.
특히 프로그래밍 언어가 저수준 최적화를 지원할 때 성능에 대해 걱정하는 것은 인간의 본성입니다. 프로그래머로서 잊지 말아야 할 것은 프로그램 성능이 우리가 최적화하고 감탄할 수있는 많은 것 중 하나 일 뿐이라는 것입니다. 프로그램 속도 외에도 우리는 자신의 공연에서 아름다움을 찾을 수 있습니다. 최대한의 시각적 출력과 사용자 인터페이스 상호 작용을 달성하기 위해 노력하면서 노력을 최소화 할 수 있습니다. 장기적으로 비트와 사이클에 대해 걱정하는 것보다 더 많은 동기 부여가 될 수 있다고 생각하십니까? 그렇습니다. string : s를 반환하십시오. 코드 크기와 노력을 최소화하고 작업량을 덜 우울하게 만듭니다.
귀하의 경우 반환 값 최적화가 수행되므로 std :: string이 복사되지 않습니다.
모듈 경계를 넘을 때주의하십시오.
그런 다음 C ++ 유형이 동일한 컴파일러의 다른 버전에서도 반드시 이진 호환되는 것은 아니기 때문에 기본 유형을 반환하는 것이 가장 좋습니다.
나는 당신이 끈을 사용해야한다는 다른 포스터에 동의합니다.
그러나 컴파일러가 임시를 얼마나 적극적으로 최적화하는지에 따라 추가 오버 헤드가 발생할 수 있습니다 (동적 문자 배열을 사용하는 것보다). (참고 : 좋은 소식은 C ++ 0a에서 rvalue 참조를 현명하게 사용하면 여기에서 효율성을 구매하기 위해 컴파일러 최적화가 필요하지 않으며 프로그래머는 품질에 의존하지 않고도 코드에 대한 추가 성능 보장을 할 수 있습니다. 컴파일러.)
귀하의 상황에서 수동 메모리 관리를 도입 할 가치가있는 추가 오버 헤드가 있습니까? 대부분의 합리적인 프로그래머는 동의하지 않을 것입니다.하지만 응용 프로그램에 성능 문제가 발생하면 다음 단계는 응용 프로그램을 프로파일 링하는 것입니다. 따라서 복잡성을 도입하면 개선이 필요하다는 좋은 증거가있을 때만 수행합니다. 전반적인 효율성.
누군가가 여기서 RVO (Return Value Optimization)가 무관하다고 언급했습니다. 동의하지 않습니다.
이에 대한 표준 텍스트 (C ++ 03)는 다음과 같습니다 (12.2).
[표준 견적 시작]
클래스 유형의 임시는 다양한 컨텍스트에서 생성됩니다. rvalue를 참조 (8.5.3)에 바인딩, rvalue (6.6.3) 반환, rvalue (4.1, 5.2.9, 5.2.11, 5.4)를 생성하는 변환 , 예외 발생 (15.1), 핸들러 입력 (15.3), 일부 초기화 (8.5). [참고 : 예외 개체의 수명은 15.1에 설명되어 있습니다. ] 임시 객체 생성을 피하더라도 (12.8) 임시 객체가 생성 된 것처럼 모든 의미 적 제한을 준수해야합니다. [예 : 복사 생성자가 호출되지 않더라도 접근성 (11 절)과 같은 의미 적 제한을 모두 만족해야한다. ]
[예:
struct X {
X (int);
X (const X &);
엑스();
};
X f (X);
무효 g ()
{
X a (1);
X b = f (X (2));
a = f (a);
}
Here, an implementation might use a temporary in which to construct X(2) before passing it to f() using X’s copy-constructor; alternatively, X(2) might be constructed in the space used to hold the argument. Also, a temporary might be used to hold the result of f(X(2)) before copying it to b using X’s copyconstructor; alternatively, f()’s result might be constructed in b. On the other hand, the expression a=f(a) requires a temporary for either the argument a or the result of f(a) to avoid undesired aliasing of a. ]
[End Standard Quote]
Essentially, the text above says that you can possibly rely on RVO in initialization situations, but not in assignment situations. The reason is, when you are initializing an object, there is no way that what you are initializing it with could ever be aliased to the object itself (which is why you never do a self check in a copy constructor), but when you do an assignment, it could.
There is nothing about your code, that inherently prohibits RVO - but read your compiler documentation to ensure that you can truly rely on it, if you do indeed need it.
I agree with duffymo. You should make an understandable working application first and then, if there is a need, attack optimization. It is at this point that you will have an idea where the major bottlenecks are and will be able to more efficiently manage your time in making a faster app.
I agree with @duffymo. Don't optimize until you have measured, this holds double true when doing micro-optimizations. And always: measure before and after you've optimized, to see if you actually changed things to the better.
Return the string, it's not that big of a loss in term of performance but it will surely ease your job afterward.
Plus, you could always inline the function but most optimizer will fix it anyways.
If you pass a referenced string and you work on that string you don't need to return anything. ;)
참고URL : https://stackoverflow.com/questions/1032243/should-i-return-stdstrings
'Program Club' 카테고리의 다른 글
| Xcode 6 Save for Enterprise Deployment가 더 이상 ipa에 대한 plist를 생성하지 않습니까? (0) | 2020.11.18 |
|---|---|
| xml 속성에서 @null의 안드로이드 의미 (0) | 2020.11.18 |
| ASP.NET MVC, Url 라우팅 : 최대 경로 (URL) 길이 (0) | 2020.11.17 |
| 동일한 메서드 이름을 가진 여러 인터페이스에서 상속 (0) | 2020.11.17 |
| Scala에서 어떻게 배열을 패턴 화합니까? (0) | 2020.11.17 |