방법: 성능 향상
업데이트: 2007년 11월
다음과 같은 방법으로 프로그래밍하면 메모리를 절약하고 장치 응용 프로그램의 성능을 향상시킬 수 있습니다.
Windows Forms 및 그래픽을 사용하여 메모리를 절약하려면
ComboBox, ListBox, ListView, ToolStripComboBox 및 TreeView와 같이 Windows Forms 및 그래픽을 제공하는 컨트롤에 대해 BeginUpdate 및 EndUpdate 메서드를 사용합니다.
컨트롤을 다시 배치할 때 SuspendLayout 및 ResumeLayout 메서드를 사용합니다.
Show() 메서드를 사용하기 전에 백그라운드에서 다른 폼을 로드하고 데이터로 컨트롤을 채웁니다.
필수 작업만 수행하도록 이벤트 처리 코드를 제한하여 보류 중인 프로세스가 계속될 수 있게 합니다.
구독자 개체를 삭제하기 전에 빼기 할당 연산자(-=)를 사용하여 해당 이벤트에 대한 구독을 취소합니다. 자세한 내용은 방법: 이벤트 구독 및 구독 취소(C# 프로그래밍 가이드)를 참조하십시오. 구독을 제대로 취소하지 않으면 메모리 누수와 유사한 문제가 발생할 수 있습니다.
오프스크린 비트맵을 사용합니다. 예제를 보려면 방법: 오프스크린으로 이미지 그리기를 참조하십시오.
키 이벤트 처리기를 추가하는 대신 컨트롤의 OnKeyDown, OnKeyPress 및 OnKeyUp 메서드를 재정의합니다.
데이터 및 문자열을 사용하여 메모리를 절약하려면
열거형의 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 형식을 참조하십시오.
함수 시그니처의 인수에 대해 InAttribute 및 OutAttribute 특성을 사용하여 불필요한 마샬링을 줄입니다.
Marshal 클래스의 메서드를 사용하여 IntPtr와 PtrToStructure, PtrToStringBSTR, GetObjectForNativeVariant 및 GetObjectForIUnknown과 같은 관리되는 개체 간을 수동으로 변환합니다.
Prelink 및 PrelinkAll 메서드를 사용하여 네이티브에서 관리로의 호출을 지원하는 스텁의 JIT 컴파일을 발생시킵니다.
네이티브 COM 개체가 일반적인 경우처럼 S_FALSE를 반환하거나, S_OK HRESULT 값이 아닌 다른 값을 반환할 것으로 예상되면 PreserveSig 필드를 true로 설정하고 관리되는 시그니처를 네이티브 시그니처와 일치하게 만듭니다. 이렇게 하면 런타임에서 HRESULT 값을 COM 호출에 대한 예외로 변환할 때 필요한 try/catch 블록에서 오버헤드가 발생하지 않습니다.
P/Invoke 호출을 여러 번 사용하지 말고 한 번의 호출에서 가능한 한 많은 작업을 수행합니다.
컬렉션에서 메모리를 절약하려면
컬렉션이 배열을 기반으로 할 경우 인덱스를 사용합니다.
동적 크기 조정을 사용하면 저장소의 크기가 지나치게 커질 수 있으므로 가능한 경우 컬렉션의 크기를 지정합니다.
제네릭 컬렉션을 사용하여 값 형식에 대한 boxing 및 unboxing 오버헤드가 발생하지 않도록 합니다. 최적화된 컬렉션을 직접 정의하여 사용하면 성능을 최대화할 수 있습니다.
XML에서 메모리를 절약하려면
더 많은 메모리를 사용하는 XmlDocument 대신 XmlTextReader 및 XmlTextWriter를 사용합니다.
성능 향상을 위해 XmlReaderSettings 및 XmlWriterSettings 설정을 지정합니다. 사용 가능한 경우 IgnoreWhitespace 및 IgnoreComments 속성 값으로 성능을 크게 향상시킬 수 있습니다.
ANSI 및 Windows 코드 페이지 인코딩보다 더 빠른 UTF-8, ASCII 및 UTF-16 문자 인코딩을 사용합니다.
구문 분석 시 스키마를 사용하면 유효성 검사 작업이 추가로 필요하므로 스키마를 사용하지 않습니다.
XML 소스를 사용하여 DataSet를 채울 때 열을 특성으로 매핑하고 형식화된 DataSet을 사용합니다.
다음 항목으로 DataSet를 채우지 않도록 합니다.
XML deserialization을 사용할 때 다음 지침에 따라 성능을 향상시킬 수 있습니다.
모든 문자에 대해 유효성 검사가 수행되므로 요소 및 특성 이름을 가능한 한 짧게 유지합니다.
특성 데이터를 기반으로 하는 XML이 요소 데이터를 기반으로 하는 XML보다 더 빠릅니다.
가능한 경우 XmlNodeReader.Skip 메서드를 사용합니다.
성능이 중요한 경우 이진 serialization을 고려합니다.
XML serialization에서 각 형식마다 XmlSerializer 인스턴스를 하나씩 사용하여 메타데이터 검색에 소요되는 시간을 줄입니다.
많은 양의 XML을 serialize하면 메모리가 많이 사용될 수 있으므로 대신 BinaryReader 및 BinaryWriter를 사용하여 사용자 지정 이진 serialization 메커니즘을 구축합니다.
웹 서비스 사용 시 메모리를 절약하려면
DataSet을 읽고 쓸 때 DiffGram을 사용합니다. 자세한 내용은 DiffGrams(ADO.NET)를 참조하십시오.
원격 DataSet 및 해당 스키마를 XML로 장치에 저장합니다.
첫 번째 호출이 후속 호출보다 더 느리므로 시작 화면이 표시되는 동안 간단한 웹 서비스 메서드를 호출합니다.
네트워크 및 데이터 오류를 주의해서 처리합니다.
경우에 따라 웹 서비스를 호출하기 전에 수동으로 DataSet을 XML 문자열로 serialize하면 성능이 향상될 수 있습니다.
고급 프로그래밍 시 메모리를 절약하려면
대규모 작업은 비동기식으로 처리합니다.
가상 호출을 피합니다. .NET Compact Framework 런타임 가상 호출은 정적 또는 인스턴스 호출보다 30%정도 느립니다. .NET Compact Framework에서는 리소스 제한으로 인해 vtable을 사용하지 않으므로 클래스 및 인터페이스 계층 구조를 탐색하여 메서드를 호출해야 하며, 이는 속도가 느린 작업입니다. .NET Compact Framework에서는 확인된 가상 호출의 캐시를 유지 관리하므로 대부분의 경우에는 호출을 다시 해석할 필요가 없습니다.
가능한 경우 속성 대신 필드를 사용합니다.
값 형식을 정의할 때 GetHashCode 및 Equals 메서드를 재정의합니다. 이러한 메서드를 재정의하지 않으면 런타임에서는 기본 ValueType 클래스에 이러한 메서드의 일반화된 버전을 사용합니다.
리플렉션을 주의하여 사용합니다. 인스턴스화되지 않은 클래스에 조사 목적으로 리플렉션을 사용하면 응용 프로그램의 인스턴스화된 개체 성능에 영향을 줄 수 있습니다.
관리되는 리소스의 이름이 정규화된 형식이며 RESX 파일에서 올바르도록 합니다. 이러한 리소스에는 올바른 버전 및 PublicKeyToken 필드가 있어야 합니다. 잘못 지정된 형식에 대해 가장 적합한 대체 형식을 찾으려고 하면 성능에 영향을 줍니다.
경우에 따라 파일에서 응용 프로그램 데이터를 직접 읽는 것만으로도 충분하며 ResourceManager를 사용하는 것보다 더 효율적일 수 있습니다. ResourceManager에서는 리소스 이진을 찾기 전에 파일 시스템의 여러 위치를 조사하여 가장 적합한 위성 어셈블리를 찾을 수 있습니다. 작업에 적합한 도구를 사용하십시오.
참고 항목
개념
.NET Compact Framework의 장치 메모리 관리