장점 - c# 전망




어느 것이 더 빠릅니까? C#의 안전하지 않은 코드 또는 원시 C++ (7)

CPU에서 실행하는 것은 CPU에서 VM을 실행하는 것보다 항상 빠를 것입니다. 나는 사람들이 다르게 주장하려고 노력하고 있다고 믿을 수 없다.

예를 들어 대기열에있는 웹 서버에서 상당히 많은 이미지 처리 작업이 있습니다. 처음에는 PHP의 GD 기능을 사용했습니다.

그들은 지옥만큼 느렸다. 우리는 C ++에서 필요한 기능을 다시 작성했습니다.

저는 비디오 프레임의 실시간 처리를 수행하는 이미지 프로세싱 프로그램을 작성하고 있습니다. C #에서 OpenCV 라이브러리 dll (관리되지 않는 C ++)을 감싸는 Emgu.CV 라이브러리 (C #)를 사용합니다. 이제는 내 자신의 특수 알고리즘을 작성해야하며 가능한 한 빨리해야합니다.

알고리즘의보다 빠른 구현은 어느 것입니까?

  1. C #에서 '안전하지 않은'함수 작성하기

  2. OpenCV 라이브러리에 함수 추가 및 Emgu.CV를 통해 호출

C # unsafe가 JIT 컴파일러를 통과하기 때문에 속도가 느린 것 같지만 그 차이가 클 것입니까?

편집하다:

VS2008에서 .NET 3.5 용으로 컴파일


그것은 영원히 분노 할 전투입니다. C 대 C ++ 대 C # 대 무엇이든. C #에서는 위험한 개념은 "위험한"작업을 잠금 해제하는 것입니다. 즉, 포인터를 사용하고 C 및 C ++ 에서처럼 포인터를 void 처리 할 수 ​​있습니다. 매우 위험하고 매우 강력합니다! 그러나 C #이 기반이었던 것을 무 찌르십시오.

요즘 마이크로 소프트는 특히 .NET 릴리스 이후로 성능의 방향으로 발전했으며 C ++에서와 같이 .NET의 다음 버전은 실제로 인라인 메서드를 지원합니다. 매우 특정한 상황에서 성능이 향상됩니다. 나는 AC # 기능이 될 수는 없지만 컴파일러가 선택하는 불쾌한 속성은 싫다.하지만 모든 것을 가질 수는 없다.

개인적으로 저는 C # 및 DirectX를 관리하고 있습니다 (이 게시물의 범위를 벗어난 XNA가 아닌 이유는 무엇입니까?). 저는 그래픽 상황에서 안전하지 않은 코드를 사용하고 있습니다. 다른 사람들이 말한 방향으로 고개를 끄덕이게합니다.

GDI ++에서 픽셀 액세스가 너무 느려서 대안을 찾지 못했기 때문입니다. 하지만 전체적으로 C # 컴파일러는 꽤 저주 받았으며 코드 비교 (기사를 찾을 수 있음)에서 성능은 C ++과 매우 유사하다는 것을 알 수 있습니다. 그것은 코드를 작성하는 더 좋은 방법이 없다는 것을 말하는 것이 아닙니다.

하루가 끝나면 개인적으로 C, C ++ 및 C #을 실행시 거의 동일한 속도로 볼 수 있습니다. 당신이 C / C ++ 군중에게 눈에 띄는 이점을 발견 할 수있는 근본적인 하드웨어 또는 그 픽셀에 매우 가깝게 가까이 일하기를 원하는 고통스러운 상황에서 그렇습니다.

하지만 오늘날 비즈니스 및 대부분의 경우 C #은 진정한 경쟁자이며 "안전한"환경에 머무르는 것은 확실히 보너스입니다.
밖에서 발을 디딜 때 안전하지 않은 코드로 대부분의 일을 처리 할 수 ​​있습니다. 그러나 그만한 가치가 있었습니까? 아마도 그렇지 않습니다. 개인적으로 C ++에서 시간 결정적 코드의 줄을 더 생각해야하는지, 그리고 C #의 모든 객체 지향 안전 항목을 고려해야하는지 궁금합니다. 하지만 나는 내가 얻을 줄 알았던 것보다 더 나은 성능을 가지고있다!

당신이 만들고있는 interop 통화의 양에주의를 기울이는 한, 당신은 두 세계의 장점을 모두 누릴 수 있습니다. 나는 그것을 개인적으로 피했지만, 어떤 비용인지는 모른다.

그래서 시도하지는 않았지만 실제로 C ++ .NET을 사용하여 모험을 듣는 것을 좋아하는 접근 방식은 이러한 특수한 그래픽 상황에 안전하지 않은 C #보다 빠른 것입니다. 그게 네이티브 C ++ 컴파일 된 코드와 어떻게 비교 될까요? 이제 질문이 있습니다!

음 ..


솔직하게 말해서, 당신이 쓰는 언어는 당신이 사용하는 알고리즘 (IMO, 어쨌든)만큼 중요하지 않습니다. 어쩌면 네이티브 코드로 가면 응용 프로그램을 더 빨리 만들 수 있지만 컴파일러, 프로그램 작성 방법, 사용중인 interop 비용의 종류에 따라 느려질 수도 있습니다 혼합 된 환경, 등등. 당신은 정말로 그것을 프로파일 링하지 않고는 말할 수 없습니다. (그리고, 당신이 당신의 어플리케이션을 프로파일 링했는지, 실제로 어디에서 시간을 보내는 지 아십니까? )

더 나은 알고리즘은 선택한 언어와 완전히 독립적입니다.


언어에는 "속도"가 없습니다. 컴파일러와 코드에 따라 다릅니다. 비효율적 인 코드를 모든 언어로 작성할 수 있으며 영리한 컴파일러는 소스의 언어와 상관없이 거의 최적의 코드를 생성합니다.

C #과 C ++ 사이의 성능에서 유일한 피할 수없는 요소는 C # 응용 프로그램이 시작시 .NET Framework 및 일부 JIT 코드를로드 할 때 더 많은 작업을 수행해야하므로 모든 작업이 동일하므로 조금 더 느리게 실행됩니다. 그 후에는 언어에 따라 달라지며, 언어가 항상 다른 언어보다 더 빨리되어야하는 근본적인 이유는 없습니다.

또한 안전하지 않은 C #이 안전성보다 더 빨리 있어야하는 이유를 알지 못합니다. 일반적으로 컴파일러는 훨씬 더 강력한 가정을 할 수 있으므로 안전성이 좋으며 안전성 더 빠를 수도 있습니다. 하지만 다시 컴파일 할 코드, 사용하는 컴파일러 및 다른 여러 가지 요인에 따라 다릅니다.

즉, 언어의 성능을 측정 할 수 있다는 생각을 포기하십시오. 당신은 할 수 없습니다. 언어는 절대로 "빠르거나 느리지"않습니다. 속도가 없습니다.


자신의 환경을 알고 있고 좋은 컴파일러를 사용한다면 (Windows에서 비디오를 처리하기 위해 인텔 C ++ 컴파일러가 최선의 선택 일 것입니다.) C ++은 몇 가지 이유로 C #을 무너 뜨릴 것입니다 :

  • C ++ 런타임 환경에는 본질적인 런타임 검사가 없습니다 (단점이라면 자유롭게 스스로를 폭파시킬 수 있습니다). C # 런타임 환경은 적어도 처음에는 계속 진행되는 온 전성 검사를 수행 할 것입니다.
  • C ++ 컴파일러는 코드 최적화를 위해 제작되었습니다. 이론적으로는 ICC (또는 GCC)가 사용하는 모든 최적화 voodo를 사용하여 C # JIT 컴파일러를 구현할 수 있지만 Microsoft의 JIT가 안정적으로 더 잘 수행 될지는 의문입니다. JIT 컴파일러에 런타임 통계가있는 경우에도 ICC 또는 GCC에서 프로필 기반 최적화만큼 좋지 않습니다.
  • C ++ 환경을 사용하면 메모리 모델을 훨씬 잘 제어 할 수 있습니다. 응용 프로그램이 데이터 캐시를 쓰러 뜨리거나 힙을 조각 낼 때까지 할당에 대한 추가 제어 권한을 부여하게됩니다. 동적 할당을 피할 수 있다면, 당신은 이미 훨씬 더 나을 것이다. (힌트 : malloc() 이나 다른 동적 할당 자의 실행 시간은 비 결정적이며, 거의 모든 비 모국어는 힙 사용이 많아 져서 할당량이 더 무거워진다. ).

열악한 컴파일러를 사용하거나 좋은 칩셋을 대상으로 할 수없는 경우 모든 베팅이 해제됩니다 .


표준 방법으로 알고리즘을 구현하려는 경우 관련이 없다고 생각합니다. 그러나 일부 언어는 apis 또는 라이브러리에 바인딩을 사용하여 비 표준적인 향상을 제공합니다.

  1. GPU 처리가 가능한지 고려하십시오 - nvidia 및 ati가 CUDA 및 CTM 프레임 워크를 제공하고 khronos 그룹 (openGL)의 지속적인 표준화 노력이 있습니다. 또한 amd가 향후 칩에 적어도 하나의 스트리밍 프로세서 코어를 추가 할 것이라는 점도 알 수 있습니다. 그래서 저는 그 지역에 상당한 약속이 있다고 생각합니다.

  2. SSE 지침을 악용 할 수 있는지, C ++ 또는 C ++에서 가장 유용한 라이브러리가 있는지, 편리한 API를 제공하는 라이브러리가 있는지 확인하십시오. "Intel Performance Primitives"및 "Math Kernel"을 기억하는 편리한 최적 라이브러리에 대한 인텔의 사이트를 확인하십시오.

그러나 정치 측면에서 알고리즘을 OpenCV에 통합하여 다른 사람들도 이익을 얻을 수 있도록하십시오.


C #은 일반적으로 C ++보다 느립니다. 관리 코드에는 런타임 검사가 있습니다. 이것은 결국 관리하게 만듭니다. C ++에서는 배열의 경계가 초과되었는지 여부를 확인할 필요가 없습니다.

내 경험에 비추어 볼 때, 고정 메모리를 사용하면 많은 도움이됩니다. 앞으로 도움이 될 .NET 4.0에는 새로운 System.IO.UnmanagedMemoryAccessor 클래스가 있습니다.





unsafe