const는 C/C++에서 어떤 최적화를 제공합니까?
가독성을 위해 참조 또는 포인터로 파라미터를 전달할 때는 가능하면 const 키워드를 사용해야 한다는 것을 알고 있습니다.인수가 일정하다고 지정하면 컴파일러가 할 수 있는 최적화가 있습니까?
몇 가지 경우가 있을 수 있습니다.
함수 파라미터:
상시 참조:
void foo(const SomeClass& obj)
상수 SomeClass 개체:
void foo(const SomeClass* pObj)
또한 SomeClass에 대한 지속적인 포인터:
void foo(SomeClass* const pObj)
변수 선언:
const int i = 1234
함수 선언:
const char* foo()
각 컴파일러가 제공하는 최적화 기능(있는 경우)은 무엇입니까?
케이스 - 1:
프로그램에서 경찰관을 선언할 때
int const x = 2;
컴파일러는 이 변수에 스토리지를 제공하지 않고 심볼 테이블에 추가함으로써 이 조건을 최적화할 수 있습니다.따라서 후속 읽기에서는 메모리에서 값을 가져오는 명령이 아니라 심볼 테이블로 리디렉션하면 됩니다.
주의: 다음과 같은 작업을 수행할 경우:
const int x = 1;
const int* y = &x;
그러면 컴파일러가 다음 컴파일러에 공간을 할당해야 합니다.x
따라서 이 경우에는 최적화가 불가능합니다.
기능 파라미터의 관점에서const
함수에서 파라미터가 변경되지 않음을 의미합니다.제가 알기로는, 이 시스템을 사용해도 성능이 크게 향상되지는 않습니다.const
정확성을 보장하기 위한 수단이라 할 수 있습니다.
케이스 - 2:
파라미터 및/또는 반환값을 const로 선언하면 컴파일러가 보다 최적의 코드를 생성하는 데 도움이 됩니까?
const Y& f( const X& x )
{
// ... do something with x and find a Y object ...
return someY;
}
컴파일러가 더 잘할 수 있는 것은 무엇입니까?파라미터 또는 반환값의 복사를 피할 수 있습니까?
아니요, 인수는 이미 참조로 전달되었습니다.
x 또는 someY 복사본을 읽기 전용 메모리에 저장할 수 있습니까?
아니, 둘 다x
그리고.someY
그 범위 밖에서 살거나 외부로부터 오거나 외부로 보내지는 것.라 할지라도someY
즉석에서 동적으로 할당됩니다.f()
그 자체와 그 소유권은 발신자에게 양도됩니다.
f() 본문 내에 표시되는 코드의 최적화는 어떻게 됩니까?const로 인해 컴파일러는 f() 본문에 대해 생성되는 코드를 개선할 수 있습니까?
const member 함수를 호출해도 컴파일러는 오브젝트의 비트가x
또는 오브젝트someY
변경되지 않습니다.게다가 다음과 같은 문제가 있습니다(컴파일러가 글로벌 최적화를 실행하지 않는 한).컴파일러는 또한 다른 어떤 코드도 같은 오브젝트에 에일리어스를 붙이는 부정수 참조를 가질 수 없다는 것을 확실히 알지 못할 수도 있습니다.x
및/또는someY
또, 같은 오브젝트에 대한 이러한 비정수 참조가, 의 실행중에 부수적으로 사용되는지 아닌지에 대해서도,f();
컴파일러는 실제 객체가 어떤 것인지조차 모를 수 있습니다.x
그리고.someY
그냥 참고문헌일 뿐이고, 애초에 상수라고 선언했었죠.
케이스 - 3:
void f( const Z z )
{
// ...
}
이것에 대해 최적화가 있습니까?
네, 컴파일러가 알고 있기 때문에z
const 오브젝트이기 때문에 글로벌 분석 없이도 몇 가지 유용한 최적화를 실행할 수 있습니다.예를 들어 본문이f()
같은 콜을 포함하다g( &z )
컴파일러는 의 비변환 부분이z
에 대한 콜 중에 변경되지 않다g()
.
답변을 드리기 전에, 사용의 이유와 사용하지 않는 이유를 강조하고 싶습니다.const
컴파일러의 최적화보다 프로그램의 정확성과 다른 개발자의 명확성을 위해서가 더 중요합니다.즉, 파라미터를 만드는 것입니다.const
메서드가 해당 파라미터를 수정하지 않을 것임을 문서화하고 멤버를 함수로 만듭니다.const
멤버가 멤버인 오브젝트를 수정하지 않는 문서(최소한 다른 const 멤버함수로부터의 출력을 논리적으로 변경하는 방법은 제외)이를 통해 개발자는 오브젝트의 불필요한 복사를 회피할 수 있습니다(원본이 파괴되거나 수정될 염려가 없기 때문에).또는 불필요한 스레드 동기화를 회피할 수 있습니다(예를 들어 모든 스레드는 단순히 읽기만 하고 문제의 오브젝트를 변환하지 않는다는 것을 알 수 있습니다).
컴파일러가 할 수 있는 최적화의 관점에서 적어도 이론적으로는 표준 C++ 코드를 파괴할 수 있는 특정 비표준 가정을 할 수 있는 최적화 모드이지만 다음을 고려하십시오.
for (int i = 0; i < obj.length(); ++i) {
f(obj);
}
「 」라고 합니다.length
함수는 '이러다'로 되어 있습니다.const
하지만 실제로는 비용이 많이 드는 작업입니다(실제로 O(1) 시간이 아닌 O(n) 시간으로 작동합니다).f
가 에의 takes by takes by by takes takes by takes takes takes takes로 됩니다.const
그러면 컴파일러는 이 루프를 다음과 같이 최적화할 수 있습니다.
int cached_length = obj.length();
for (int i = 0; i < cached_length; ++i) {
f(obj);
}
가 '''로 입니다'''로 되어 있습니다.f
의 변경을 실시하지 .이 파라미터는 되지 않습니다.length
객체가 변경되지 않은 경우 함수는 매번 동일한 값을 반환해야 합니다. 「」의 경우는, 「」입니다.f
된 후, 「」를 참조해 주세요.length
.f
값이 변경되도록 개체를 수정했을 수 있습니다.
된 바와 같이 로 하고 전제(를 들어 " " " 등)를 할 수 합니다.const
가 절대 할 수 .const_cast
계속하다
SomeClass* const pObj
을 사용법이러한 오브젝트를 변경하는 안전한 방법은 존재하지 않기 때문에 예를 들어 컴파일러는 주소를 사용하더라도 하나의 메모리 읽기만으로 레지스터에 캐시할 수 있습니다.
은 특별히, ''는 활성화하지 않습니다.const
타입의 한정자는 과부하 해결에 영향을 주고, 다른 고속의 기능이 선택될 가능성이 있습니다.
const의 정확한 효과는 사용되는 컨텍스트마다 다릅니다.변수를 선언할 때 const를 사용하면 물리적으로 일정하며 읽기 전용 메모리에 상주합니다.
const int x = 123;
항상성을 버리려고 하는 것은 정의되지 않은 행동입니다.
const_cast는 포인터 또는 참조에서 항상성 또는 휘발성을 제거할 수 있지만 결과 포인터 또는 참조를 사용하여 const로 선언된 객체에 쓰거나 volatile로 선언된 객체에 액세스하면 정의되지 않은 동작을 호출합니다.cppreference/const_cast
이 는 이 이 '비슷하다'라고할 수 .x
있다123
이것에 의해, 어느 정도의 최적화 가능성이 생깁니다(항상 전파).
기능에 대해서는 다른 문제입니다.예를 들어 다음과 같습니다.
void doFancyStuff(const MyObject& o);
의 기능doFancyStuff
가지고 중 를 할 수 o
.
- 개체를 수정하지 마십시오.
- 일관성을 버리고 대상을 수정하다
- MyObject의 데이터 멤버 수정
const로 선언된 MyObject 인스턴스에서 함수를 호출하면 #2로 정의되지 않은 동작이 호출됩니다.
구루 질문: 다음은 정의되지 않은 행동을 일으킬 것인가?
const int x = 1;
auto lam = [x]() mutable {const_cast<int&>(x) = 2;};
lam();
함수 파라미터:
const
참조된 메모리에서는 중요하지 않습니다.마치 옵티마이저의 등 뒤에서 손을 묶는 것 같아요.
른른른른고고고고고고고고고고(((((((((((().void bar()
의 in ) ) 。foo
이치노.에 의한 제한 를 알 수 때문입니다. 왜냐하면 옵티마이저는 다음 중 어느 쪽인지 알 수 있는 방법이 없기 때문입니다.bar
하였습니다.foo
( 「 「 」 ), 이에 큰 .메모리를 외부에서 수정하거나 에일리어스를 지정하면 이 영역의 옵티마이저에 큰 제약이 생깁니다.
물어보진 않았지만const
최적화 도구에 대한 최적화가 보장되기 때문에 함수 매개 변수의 값은 최적화를 허용합니다.const
물건.물론 이 매개변수를 복사하는 비용은 최적화 도구의 이점보다 훨씬 더 높을 수 있습니다.
참조: http://www.gotw.ca/gotw/081.htm
변수 선언:
const int i = 1234
이는 선언 위치, 생성 시기 및 유형에 따라 달라집니다.이 카테고리는 주로const
최적화가 존재합니다.수정은 정의되어 있지 않습니다.const
오브젝트 또는 알려진 상수이므로 컴파일러는 몇 가지 최적화를 수행할 수 있습니다.이것에 의해, 정의되지 않은 동작이 호출되지 않는 것을 전제로 해, 몇개의 보증이 도입됩니다.
const int A(10);
foo(A);
// compiler can assume A's not been modified by foo
옵티마이저는 변경되지 않는 변수도 식별할 수 있습니다.
for (int i(0), n(10); i < n; ++i) { // << n is not const
std::cout << i << ' ';
}
함수 선언:
const char* foo()
중요하지 않다.참조된 메모리는 외부에서 수정할 수 있습니다.참조된 변수가 에 의해 반환된 경우foo
옵티마이저는 최적화를 할 수 있지만, 이는 의 존재/유무와는 무관합니다.const
함수의 반환 유형으로 이동합니다.
다시 한 번 말씀드리지만const
값 또는 개체가 다릅니다.
extern const char foo[];
언급URL : https://stackoverflow.com/questions/27466642/what-kind-of-optimization-does-const-offer-in-c-c
'programing' 카테고리의 다른 글
Vue의 온드래거에 상당합니다.드래그 가능(Sortable.js) (0) | 2022.08.14 |
---|---|
Mac OS X의 clock_gettime 대체 기능 (0) | 2022.08.14 |
Vuex 스토어 모듈 상태 개체를 비우는 방법 (0) | 2022.08.14 |
왜 매크로가 함수가 아닌 어설트일까요? (0) | 2022.08.14 |
C의 2가지 미완성 구현이 있습니까? (0) | 2022.08.13 |