다음을 통해 공유


방법: 성능 향상

업데이트: 2007년 11월

다음과 같은 방법으로 프로그래밍하면 메모리를 절약하고 장치 응용 프로그램의 성능을 향상시킬 수 있습니다.

Windows Forms 및 그래픽을 사용하여 메모리를 절약하려면

  • ComboBox, ListBox, ListView, ToolStripComboBoxTreeView와 같이 Windows Forms 및 그래픽을 제공하는 컨트롤에 대해 BeginUpdate 및 EndUpdate 메서드를 사용합니다.

  • 컨트롤을 다시 배치할 때 SuspendLayoutResumeLayout 메서드를 사용합니다.

  • Show() 메서드를 사용하기 전에 백그라운드에서 다른 폼을 로드하고 데이터로 컨트롤을 채웁니다.

  • 필수 작업만 수행하도록 이벤트 처리 코드를 제한하여 보류 중인 프로세스가 계속될 수 있게 합니다.

  • 구독자 개체를 삭제하기 전에 빼기 할당 연산자(-=)를 사용하여 해당 이벤트에 대한 구독을 취소합니다. 자세한 내용은 방법: 이벤트 구독 및 구독 취소(C# 프로그래밍 가이드)를 참조하십시오. 구독을 제대로 취소하지 않으면 메모리 누수와 유사한 문제가 발생할 수 있습니다.

  • 오프스크린 비트맵을 사용합니다. 예제를 보려면 방법: 오프스크린으로 이미지 그리기를 참조하십시오.

  • 키 이벤트 처리기를 추가하는 대신 컨트롤의 OnKeyDown, OnKeyPressOnKeyUp 메서드를 재정의합니다.

데이터 및 문자열을 사용하여 메모리를 절약하려면

  • for 루프에 개체 변수 대신 정수 변수(Int32 또는 Int64)를 사용합니다.

  • 열거형의 ToString 메서드는 메타데이터 테이블을 검색하여 성능에 영향을 줄 수 있으므로 가능하면 사용하지 않습니다.

  • OutOfMemoryException 오류가 발생하지 않도록 합니다. 내부적 용도 또는 새 개체 인스턴스에 할당할 수 있는 메모리가 충분하지 않으면 공용 언어 런타임에서 이 예외를 throw합니다. 이 예외가 발생하지 않게 하려면 64KB 이상의 메모리를 사용하는 큰 메서드를 가능하면 프로그래밍하지 않아야 합니다.

  • 예외 대화 상자에 대한 오류 메시지 문자열을 포함하는 System.SR.dll을 제거합니다. 메모리 절약을 위해 이 파일을 제외하고 응용 프로그램을 배포할 수 있습니다. 파일이 있으면 .NET Compact Framework에서 System.SR.dll에 들어 있는 오류 문자열을 동적으로 로드합니다.

    장치에 이 .dll 파일이 없으면 모든 예외에 대해 "리소스 어셈블리를 로드할 수 없습니다."라는 메시지가 표시됩니다. 그러나 개발 도중에는 의미 있는 예외가 표시되도록 System.SR.dll에 대한 참조를 Visual Studio 프로젝트에 추가하는 것이 좋습니다.

  • 문자열은 변경되지 않으므로 문자열을 수정할 때마다 String 개체가 새로 만들어집니다. 자주 수정되는 문자열을 생성할 때는 StringBuilder를 사용하는 것이 좋습니다.

  • DateTime serialization에 사용된 정확한 형식을 알고 있는 경우 DateTime에 대해 ParseExact 메서드를 사용합니다. 그렇지 않으면 DateTime 파서는 몇 가지 문화권 관련 형식을 순차적으로 적용하려고 합니다.

  • 열린 SqlCeCommand 개체의 수를 제한하고 작업이 끝나면 삭제합니다.

네이티브 코드와 상호 운용될 때 메모리를 절약하려면

  • 플랫폼 호출 작업에서 Int32 또는 IntPtr와 같이 관리되는 메모리와 관리되지 않는 메모리 둘 다에서 공통적인 표현을 갖는 blittable 형식을 사용합니다. 32비트보다 큰 blittable 값 형식은 값보다 참조로 전달하는 것이 더 빠릅니다. blittable 형식에 대한 자세한 내용은 .NET Compact Framework Blittable 형식을 참조하십시오.

  • 함수 시그니처의 인수에 대해 InAttributeOutAttribute 특성을 사용하여 불필요한 마샬링을 줄입니다.

  • Marshal 클래스의 메서드를 사용하여 IntPtrPtrToStructure, PtrToStringBSTR, GetObjectForNativeVariantGetObjectForIUnknown과 같은 관리되는 개체 간을 수동으로 변환합니다.

  • PrelinkPrelinkAll 메서드를 사용하여 네이티브에서 관리로의 호출을 지원하는 스텁의 JIT 컴파일을 발생시킵니다.

  • 네이티브 COM 개체가 일반적인 경우처럼 S_FALSE를 반환하거나, S_OK HRESULT 값이 아닌 다른 값을 반환할 것으로 예상되면 PreserveSig 필드를 true로 설정하고 관리되는 시그니처를 네이티브 시그니처와 일치하게 만듭니다. 이렇게 하면 런타임에서 HRESULT 값을 COM 호출에 대한 예외로 변환할 때 필요한 try/catch 블록에서 오버헤드가 발생하지 않습니다.

  • P/Invoke 호출을 여러 번 사용하지 말고 한 번의 호출에서 가능한 한 많은 작업을 수행합니다.

컬렉션에서 메모리를 절약하려면

  • 컬렉션이 배열을 기반으로 할 경우 인덱스를 사용합니다.

  • 동적 크기 조정을 사용하면 저장소의 크기가 지나치게 커질 수 있으므로 가능한 경우 컬렉션의 크기를 지정합니다.

  • 제네릭 컬렉션을 사용하여 값 형식에 대한 boxing 및 unboxing 오버헤드가 발생하지 않도록 합니다. 최적화된 컬렉션을 직접 정의하여 사용하면 성능을 최대화할 수 있습니다.

XML에서 메모리를 절약하려면

  • 더 많은 메모리를 사용하는 XmlDocument 대신 XmlTextReaderXmlTextWriter를 사용합니다.

  • 성능 향상을 위해 XmlReaderSettingsXmlWriterSettings 설정을 지정합니다. 사용 가능한 경우 IgnoreWhitespaceIgnoreComments 속성 값으로 성능을 크게 향상시킬 수 있습니다.

  • ANSI 및 Windows 코드 페이지 인코딩보다 더 빠른 UTF-8, ASCII 및 UTF-16 문자 인코딩을 사용합니다.

  • 구문 분석 시 스키마를 사용하면 유효성 검사 작업이 추가로 필요하므로 스키마를 사용하지 않습니다.

  • XML 소스를 사용하여 DataSet를 채울 때 열을 특성으로 매핑하고 형식화된 DataSet을 사용합니다.

  • 다음 항목으로 DataSet를 채우지 않도록 합니다.

    • 스키마 유추

    • 중첩된 테이블

    • 몇 개의 DateTime 열. 성능 향상을 위해 Ticks 속성 값을 대신 사용하십시오.

  • XML deserialization을 사용할 때 다음 지침에 따라 성능을 향상시킬 수 있습니다.

    • 모든 문자에 대해 유효성 검사가 수행되므로 요소 및 특성 이름을 가능한 한 짧게 유지합니다.

    • 특성 데이터를 기반으로 하는 XML이 요소 데이터를 기반으로 하는 XML보다 더 빠릅니다.

    • 가능한 경우 XmlNodeReader.Skip 메서드를 사용합니다.

    • 성능이 중요한 경우 이진 serialization을 고려합니다.

  • XML serialization에서 각 형식마다 XmlSerializer 인스턴스를 하나씩 사용하여 메타데이터 검색에 소요되는 시간을 줄입니다.

  • 많은 양의 XML을 serialize하면 메모리가 많이 사용될 수 있으므로 대신 BinaryReaderBinaryWriter를 사용하여 사용자 지정 이진 serialization 메커니즘을 구축합니다.

웹 서비스 사용 시 메모리를 절약하려면

  • DataSet을 읽고 쓸 때 DiffGram을 사용합니다. 자세한 내용은 DiffGrams(ADO.NET)를 참조하십시오.

  • 원격 DataSet 및 해당 스키마를 XML로 장치에 저장합니다.

  • 첫 번째 호출이 후속 호출보다 더 느리므로 시작 화면이 표시되는 동안 간단한 웹 서비스 메서드를 호출합니다.

  • 네트워크 및 데이터 오류를 주의해서 처리합니다.

  • 경우에 따라 웹 서비스를 호출하기 전에 수동으로 DataSet을 XML 문자열로 serialize하면 성능이 향상될 수 있습니다.

고급 프로그래밍 시 메모리를 절약하려면

  • 대규모 작업은 비동기식으로 처리합니다.

  • 가상 호출을 피합니다. .NET Compact Framework 런타임 가상 호출은 정적 또는 인스턴스 호출보다 30%정도 느립니다. .NET Compact Framework에서는 리소스 제한으로 인해 vtable을 사용하지 않으므로 클래스 및 인터페이스 계층 구조를 탐색하여 메서드를 호출해야 하며, 이는 속도가 느린 작업입니다. .NET Compact Framework에서는 확인된 가상 호출의 캐시를 유지 관리하므로 대부분의 경우에는 호출을 다시 해석할 필요가 없습니다.

  • 가능한 경우 속성 대신 필드를 사용합니다.

  • 값 형식을 정의할 때 GetHashCodeEquals 메서드를 재정의합니다. 이러한 메서드를 재정의하지 않으면 런타임에서는 기본 ValueType 클래스에 이러한 메서드의 일반화된 버전을 사용합니다.

  • 리플렉션을 주의하여 사용합니다. 인스턴스화되지 않은 클래스에 조사 목적으로 리플렉션을 사용하면 응용 프로그램의 인스턴스화된 개체 성능에 영향을 줄 수 있습니다.

  • 관리되는 리소스의 이름이 정규화된 형식이며 RESX 파일에서 올바르도록 합니다. 이러한 리소스에는 올바른 버전 및 PublicKeyToken 필드가 있어야 합니다. 잘못 지정된 형식에 대해 가장 적합한 대체 형식을 찾으려고 하면 성능에 영향을 줍니다.

  • 경우에 따라 파일에서 응용 프로그램 데이터를 직접 읽는 것만으로도 충분하며 ResourceManager를 사용하는 것보다 더 효율적일 수 있습니다. ResourceManager에서는 리소스 이진을 찾기 전에 파일 시스템의 여러 위치를 조사하여 가장 적합한 위성 어셈블리를 찾을 수 있습니다. 작업에 적합한 도구를 사용하십시오.

참고 항목

개념

.NET Compact Framework의 장치 메모리 관리

.NET Compact Framework 방법 항목

기타 리소스

.NET Compact Framework의 성능 및 진단