developer tip

C ++ 스타일 캐스트의 성능 저하?

copycodes 2020. 12. 28. 08:25
반응형

C ++ 스타일 캐스트의 성능 저하?


저는 C ++ 스타일 캐스트를 처음 했고, 인터럽트 서비스 루틴에 실시간으로 중요한 기한 이 있기 때문에 C ++ 스타일 캐스트를 사용하면 애플리케이션 성능이 저하 될까 걱정됩니다 .

일부 캐스트는 예외를 던질 것이라고 들었습니다!

C ++ 스타일 캐스트를 사용하면 내 코드가 더 "견고"할 수 있기 때문입니다. 그러나 성능 저하가있는 경우 C ++ 스타일 캐스트를 사용하지 않고 대신 C 스타일 캐스트를 사용하는 코드를 테스트하는 데 더 많은 시간을 할애 할 것입니다.


C ++ 스타일 캐스트와 C 스타일 캐스트의 성능을 비교하기 위해 엄격한 테스트 / 프로파일 링을 수행 한 사람이 있습니까?

결과는 어땠습니까?

어떤 결론을 내렸습니까?


C ++ 스타일 캐스트가 개념적으로 C 스타일 캐스트로 대체 될 수 있다면 오버 헤드가 없습니다. dynamic_castC에 해당하는 항목이 없는에서와 같이 할 수없는 경우 비용을 어떤 방식 으로든 지불해야합니다.

예를 들어, 다음 코드 :

int x;
float f = 123.456;

x = (int) f;
x = static_cast<int>(f);

VC ++로 두 캐스트 모두에 대해 동일한 코드를 생성합니다. 코드는 다음과 같습니다.

00401041   fld         dword ptr [ebp-8]
00401044   call        __ftol (0040110c)
00401049   mov         dword ptr [ebp-4],eax

던질 수있는 유일한 C ++ 캐스트 dynamic_cast는 참조로 캐스트 할 때입니다. 이를 방지하려면 캐스트가 실패하면 0을 반환하는 포인터로 캐스트하십시오.


런타임에 추가 비용이 드는 유일한 것은 dynamic_cast이며 어쨌든 C 스타일 캐스트로 직접 재현 할 수없는 기능을 가지고 있습니다. 그래서 문제 없습니다.

이를 확인하는 가장 쉬운 방법은 컴파일러에게 어셈블러 출력을 생성하도록 지시하고 생성하는 코드를 검사하는 것입니다. 예를 들어, 깔끔하게 구현 된 컴파일러에서 reinterpret_cast모두 사라질 것입니다. 왜냐하면 "맹목적으로 앞서 가고 데이터가이 유형 인 척"을 의미하기 때문입니다.


성능 저하가 발생하는 이유는 무엇입니까? C 캐스트와 정확히 동일한 기능을 수행 합니다 . 유일한 차이점은 컴파일 타임에 더 많은 오류를 포착하고 소스 코드에서 검색하기가 더 쉽다는 것입니다.

static_cast<float>(3)과 정확히 동일하며 (float)3정확히 동일한 코드를 생성합니다.

a float f = 42.0f reinterpret_cast<int*>(&f)는과 정확히 동일하며 (int*)&f정확히 동일한 코드를 생성합니다.

등등. 다른 유일한 캐스트 dynamic_cast는 예외를 던질 수 있습니다. 하지만 C 스타일 캐스트가 할 수없는 일을하기 때문이다. 따라서 dynamic_cast기능이 필요 하지 않으면 사용 하지 마십시오 .

일반적으로 컴파일러 작성자가 지능적이라고 가정하는 것이 안전합니다. 표준에 따라 동일한 의미를 가진 두 개의 다른 표현식이 주어지면 일반적으로 컴파일러에서 동일하게 구현 될 것이라고 가정하는 것이 안전합니다.

아차 : 두 번째 예는 물론,하지 dynamic_cast는, reinterpret_cast해야합니다. 지금 고쳤습니다.

네, 확실히하기 위해 C ++ 표준이 말하는 것은 다음과 같습니다.

§5.4.5 :

수행 한 변환

  • a const_cast(5.2.11)
  • a static_cast(5.2.9)
  • a static_cast다음에 aconst_cast
  • a reinterpret_cast(5.2.10) 또는
  • a reinterpret_cast다음에 const_cast.

명시 적 유형 변환의 캐스트 표기법을 사용하여 수행 할 수 있습니다. 동일한 의미 제한 및 동작이 적용됩니다. 변환이 위에 나열된 방법 중 두 가지 이상으로 해석 될 수있는 경우 해당 해석으로 인한 캐스트의 형식이 잘못된 경우에도 목록에 첫 번째로 나타나는 해석이 사용됩니다.

그렇다면 아무것도 는 C 스타일 캐스트는 C ++ 캐스트의 관점에서 구현되기 때문에, C 스타일 캐스트해야 느린 . (물론 그렇지 않습니다. 컴파일러가 어떤 경우에도 동일한 코드를 생성하기 때문입니다.하지만 C ++ 스타일의 캐스트가 더 느리다는 것보다 더 그럴듯합니다.)


4 개의 C ++ 스타일 캐스트가 있습니다.

  • const_cast
  • static_cast
  • reinterpret_cast
  • dynamic_cast

이미 언급했듯이 처음 세 가지는 컴파일 타임 작업입니다. 그것들을 사용하는 것에 대한 런타임 패널티는 없습니다. 한 가지 방식으로 선언 된 데이터를 다른 방식으로 액세스해야한다는 컴파일러에 대한 메시지입니다. "나는 이것이라고 말 int*했지만 s를 char*가리키는 것처럼 액세스하도록하겠습니다. sizeof(int) char"또는 "이 데이터가 읽기 전용이라고 말했고 이제 수정하지 않을 함수에 전달해야하지만 매개 변수를 const 참조로 사용하지 않습니다. "

잘못된 유형으로 캐스트하고 데이터 (항상 C 스타일 캐스트의 가능성이 있음)에 대한 데이터 손상을 제외하고 이러한 캐스트의 가장 일반적인 런타임 문제는 실제로 선언 된 데이터를 const상수가 아닌 데이터로 캐스트 할 수 없다는 것입니다. constnon-const로 선언 된 것을 캐스팅 한 다음 수정하는 것은 정의되지 않습니다. Undefined는 충돌이 발생하지 않을 수도 있음을 의미합니다 .

dynamic_cast 런타임 구조이며 런타임 비용이 있어야합니다.

이 캐스트의 가치는 캐스팅하려는 대상을 구체적으로 말하고 시각적으로 튀어 나와 뇌사 도구로 검색 할 수 있다는 것입니다. C 스타일 캐스트를 사용하는 것보다 사용하는 것이 좋습니다.


사용하는 경우 dynamic_cast몇 가지 검사를 (더에서 바보 같은 일에서 당신을 방지하기 위해 런타임 동안 만들어진 GCC 메일 링리스트 ), 하나의 비용은 dynamic_cast, 어떤 클래스 등의 영향을 영향을 얼마나 많은 클래스에 따라
확실 정말 경우 캐스트는 안전하지만 reinterpret_cast.


"런타임에 추가 비용이 발생하는 유일한 방법은"입니다. "라는 말에 동의하지만 dynamic_cast컴파일러 별 차이가있을 수 있습니다.

C 스타일과 C ++ 스타일 static_cast캐스트 를 사용하는지 여부에 따라 코드 생성 또는 최적화가 약간 다른 현재 컴파일러에 대해 몇 가지 버그가 제기 된 것을 보았습니다 .

So if you're worried, check the disassembly on hotspots. Otherwise just avoid dynamic casts when you don't need them. (If you turn off RTTI, you can't use dynamic_cast anyway.)


The canonical truth is the assembly, so try both and see if you get different logic.

If you get the exact same assembly, there is no difference- there can't be. The only place you really need to stick with the old C casts is in pure C routines and libraries, where it makes no sense to introduce C++ dependence just for type casting.

One thing to be aware of is that casts happen all over the place in a decent sized piece of code. In my entire career I've never searched on "all casts" in a piece of logic- you tend to search for casts to a specific TYPE like 'A', and a search on "(A)" is usually just as efficient as something like "static_cast<A>". Use the newer casts for things like type validation and such, not because they make searches you'll never do anyway easier.

ReferenceURL : https://stackoverflow.com/questions/674982/performance-hit-from-c-style-casts

반응형