C #에서 관리되지 않는 안전 코드를 사용하지 않는 이유


10

C #에는 검사되지 않은 코드를 실행하는 옵션이 있습니다. 관리되는 코드가 훨씬 안전하고 많은 문제를 극복하므로 일반적으로 권장하지 않습니다.

그러나 코드에서 오류가 발생하지 않는다고 확신하고 메모리를 처리하는 방법을 알고 있다면 왜 (빠른 코드를 좋아한다면) 일반적인 조언을 따르는 지 궁금합니다.

비디오 카메라 용 프로그램을 작성했기 때문에 이것이 매우 궁금합니다. 비트 맵 조작이 매우 빠릅니다. 빠른 그래픽 알고리즘을 직접 만들었으며 관리되지 않는 코드를 사용하여 비트 맵에서 훌륭하게 작동합니다.

이제 일반적으로 메모리 누수 또는 충돌 위험이 없다고 확신한다면 관리되지 않는 코드를 더 자주 사용하지 않는 이유는 무엇입니까?

추신 : 내 프로그래밍 배경 : 나는이 프로그래밍 세계에 뛰어 들었고 나는 혼자 일한다 (몇 년 동안 그렇게한다). 그리고 나는이 소프트웨어 디자인 질문이 그렇게 이상하지 않기를 바란다. 나는 그런 것들을 요구하는 선생님과 같은 다른 사람들이 실제로 없습니다.


8
unsafe수단 "당신이 무슨 일을하는지 알고 있고, 위험에 대한 혜택을 단다." 필자는 unsafe몇 번이나 사용해 왔으며 , 항상 고유 한 방식으로 성능을 떨어 뜨릴 수있는 성능과 관련이있는 특정 목적을위한 것이 었습니다. 대부분의 경우 추가 성능 이점이 안전 손실의 가치가 없기 때문에 일반적인 프로그래밍 기술로 사용하지 않습니다.
— Robert Harvey

14
몇 년 동안 때때로 충돌하거나 메모리 누수가 발생한 많은 코드를 작성하여 메모리 누수 또는 충돌 위험이없는 것으로 확신했습니다.
— whatsisname

1
좋은 unsafe사용 사례 는 다음과 같습니다 . stackoverflow.com/q/11660127/102937
— Robert Harvey

3
비트 맵 코드에 여전히 버그가있는 것 같지만 감지하지 못했습니다. 그렇지 않은 경우에도 기존 코드에 새로운 요구 사항을 구현해야 할 때까지 기다리십시오.
— Doc Brown

1
코드가 오류를 일으키지 않을지라도 여전히 오류를 유발하기 때문에.
— user253751

답변:


27

글쎄, 그것은 주로 나이가 많은 노인의 경우입니다.

  • 최적화하지 마십시오
  • (전문가 만 해당) 아직 최적화하지 마십시오

그러나 실제로 안전하지 않은 코드를 피하는 세 가지 주요 이유를 생각할 수 있습니다.

  1. 버그 : 질문의 중요한 부분은 "코드가 오류를 유발하지 않는다"고 확신하는 것입니다. 글쎄, 당신은 어떻게 완전히 전적으로 확신 할 수 있습니까? 코드의 정확성을 보장하는 공식적인 방법으로 증명자를 사용 했습니까? 한 가지 확실한 것은 프로그래밍에서 확실하며 버그가있을 것입니다. 안전을 해제 할 때 새로운 종류의 버그가 통과 할 수 있습니다. 가비지 수집기가 메모리를 처리하게하면 많은 문제가 해결됩니다.

  2. 항상 당신이 생각하는 것만 큼 빠르지는 않습니다 : 다른 요점은 : 문제에 따라 이득이 그렇게 크지 않을 수 있습니다. 지금 당장 찾을 수는 없지만 Java, Scala, Go 및 C ++의 속도를 비교 한 Google의 연구를 기억합니다. 지면에 최적화되면 물론 C ++이 훨씬 빨라졌습니다. 그러나 "아이디 오 매틱"방식으로 프로그래밍 된 알고리즘은 실제로 그렇게 빠르지는 않았습니다. 표준 구조와 관용구 (stl 컨테이너, 롤되지 않은 루프 등)를 사용한다는 의미에서 관용적입니다. Microsoft는 C # 및 C ++와 비슷한 실험을 수행했습니다. 최고의 Microsoft 엔지니어 중 하나 인 Raymond Chen은 C #을이기려면 std :: string을 직접 구현해야했습니다. ( http://www.codinghorror.com/blog/2005/05/on-managed-code-performance-again.html 참조)) 훨씬 적은 노력으로 관리 코드에서 꽤 괜찮은 성능을 얻었으므로 종종 문제가되지 않습니다.

  3. 재사용 성 : 안전하지 않은 코드는 완전 신뢰 환경에서만 사용할 수 있습니다. 예를 들어 ASP.NET 서버에서는 일반적으로 안전하지 않은 코드를 사용할 수 없습니다. 버퍼 오버플로로 인해 취약점이 발생하기 쉽습니다. 또 다른 예는 clickonce입니다. 또는 네트워크 공유에서 응용 프로그램에 액세스 한 경우. 따라서 다양한 배포 시나리오에서 코드를 사용하려는 경우 안전하지 않은 코드가 사용되지 않습니다.

그래서 기본적으로 : 불필요한 버그가 발생할 수 있기 때문에 눈살을 찌푸리고 전혀 이득을 얻지 못할 수 있으며 코드의 재사용 성을 감소시킵니다.

그러나 시나리오에서 실제로 성능을 요구하고 (증명할 데이터가있는 경우) 메모리를 처리하는 방법을 알고 숙련 된 프로그래머라면 제어 된 환경에서 코드를 사용할 것입니다.


4

어떤 방식으로 관리되지 않는 코드는 일종의 지불 방식입니다. 추가 개발 노력으로 더 빠른 실행을 구매합니다. 실제로 관리되지 않는 코드는 개발, 디버깅 및 유지 관리에 더 많은 시간이 필요합니다. 정확하게 참여하는 것은 대부분의 참가자에게 어려운 일입니다. 어떤 방식으로, 이것은 어셈블리에서의 프로그래밍과 유사합니다. 물론, 어셈블리 *로 쓰면 CPU에서 더 많은 전력을 짜낼 수 있지만, 그 경로에 더 많은 노력을 기울입니다.

때로는 개발 시간의 차이가 시간이 아닌 며칠로 매우 중요합니다. 그러나 실행 속도의 차이는 그리 크지 않습니다. 그렇기 때문에 관리되지 않는 코드의 개발이 오디오 및 비디오 처리와 같은 리소스 배고픈 알고리즘의 현지화되고 자체 포함 된 구현에서 설명한 것과 유사한 상황을 위해 예약 된 이유입니다.

본질적으로 귀하의 질문에 대한 답변은 왜 모든 사람이 페라리를 운전하지 않는지에 대한 답변과 비슷합니다. 불행히도 모든 사람이 감당할 수있는 것은 아닙니다.


* 컴파일러의 최적화 기술에서 지난 수십 년간의 발전은이 격차를 좁혀 더 이상 확실한 내기가 아닙니다.


0

수학적 의미에서 정확성 또는 다른 제약에 대해 "확실히"(즉, 증명해야 함)하는 것은 명령형 언어에서 매우 어려운 문제이기 때문입니다. 프로그램은 종종 상태가 많기 때문에 가능한 각 상태를 확인해도 확인할 수 없습니다. 건설적인 증거를 만드는 것은 자동화 할 수있는 것이 아닙니다.

그 이유는 실행을 관리하는 보험이 안전하지 않은 코드로 얻을 수있는 작은 성능 향상을 초과하는 경우가 많기 때문입니다. 물론 이것은 특정 사용 사례에 따라 다릅니다.


1
나는 그것이 이유에 정확성 또는 단순 아무 상관이 있다고 생각하지 않습니다 ..
— 지미 호파에게

아무도 공식적인 정확성 증명에 대해 이야기하고 있지 않습니다.

1
귀하의 게시물이 요점을 놓칠 것이라고 확신하지만 공식적인 증거는 제시하지 않습니다. 마찬가지로, 프로그램을 한 번에 모두 증명하지 않고도 내 프로그램이 정확하다는 것을 확신 할 수 있습니다 (예 : 광범위한 테스트, 디버깅 및 버그가 발생하지 않고 장기간 실제 사용). 이 해석은 대부분의 사람들이 "정확하다"고 말할 때 대부분의 의미에 더 가깝습니다. 공식적인 방법은 틈새 시장의 관심사이며 대부분의 개발자는 완전히 고려하지 않습니다.

1
그런 질문은 없습니다. 내가 읽을 때 문제는 관리되는 세계의 탈출 해치가 더 자주 사용되지 않아야하는 이유에 대한 것입니다 (관리 코드의 기본값을 지정하는 것이 의미 함). 어쨌든 (정확성을 보장하는 경도를 지적함으로써) 그 질문 에 대답하고 싶다면 정확성에 대한 절대적이고 공식적인 보증에 대해 이야기하지 않고 그렇게 할 수 있습니다 . 현재 귀하의 답변은 명령형 언어에 대한 완전하고 정확한 정확성 증명을 중심으로 이루어집니다. 그러나 그것은 과잉이며 관리되는 C #에 대한 증거는 똑같이 (또는 거의) 어렵다고 생각합니다.

1
@fish : 당신이 무슨 말을하는지 알 수 있습니다. 증명하기 어려운 것과 추론하기 어려운 것 사이에는 상관 관계가 있습니다. 올바르게 증명하기가 어렵다면, 그것이 옳다는 것을 확신하기가 어려울 것입니다.
— Michael Shaw

0

요컨대, C ++ 환경에서 프로그램의 모든 작업을 수행하고 비트와 볼트를 관리하는 데 방해가되는 것은 없습니다. 가비지 수집기없이 모든 메모리 후프 및 누출을 올바르게 관리 할 수 ​​있다고 확신하면 C ++에서이를 환영합니다. :)

반대로 C #은 .NET 프레임 워크에서 안전하게 실행하기 위해 안전하고 관리되며 강력한 형식의 개발 환경을 제공한다는 이점이 있습니다.

관리되지 않는 코드 프로그래밍의 가능한 백 드로우는 개발 시간이 길고 자세한 테스트를위한 시간 할당입니다. 물론 처리 속도를 높이고 소프트웨어 실행 방식을 보다 강력하게 제어 할 수 있습니다.

따라서 4.0부터 .NET Framework에서 관리되지 않는 코드로 작업하는 옵션은 코드를 사용하지 않는 것보다 이익을 얻을 수있는 경우에 대한 옵션입니다 ...


Aha는 흥미로운 점입니다. 제가 마이크로 컨트롤러 세계
— 왔으며
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.