2009-07-07 4 views
8

저는 소형 프레임 워크 응용 프로그램을 개발 중이므로 성능을 향상시켜야합니다. 이 응용 프로그램은 현재 개체를 XML로 serialize하고 데이터베이스에 저장하여 오프라인으로 작동합니다. 프로파일 링 도구를 사용하면 앱이 느려지면서 오버 헤드가 커지는 것을 알 수있었습니다. 필자는 바이너리 직렬화로 전환하면 성능이 향상 될 것이라고 생각했지만, 이것이 소형 프레임 워크에서 지원되지 않기 때문에 protobuf-net을 살펴 보았습니다. 직렬화는 더 빨라지지만 비 직렬화는 훨씬 느려지고 응용 프로그램은 직렬화보다 직렬화를 더 많이 수행하고 있습니다.XML과 직렬화/직렬화 해제 용 이진 성능

이진 직렬화가 더 빨라야합니까? 그렇다면 성능 향상을 위해 무엇을 할 수 있습니까? 여기에 내가 XML 및 바이너리를 모두 사용하고 방법의 조각입니다 :

XML 직렬화 :

public string Serialize(T obj) 
{ 
    UTF8Encoding encoding = new UTF8Encoding(); 
    XmlSerializer serializer = new XmlSerializer(typeof(T)); 
    MemoryStream stream = new MemoryStream(); 
    XmlTextWriter writer = new XmlTextWriter(stream, Encoding.UTF8); 
    serializer.Serialize(stream, obj); 
    stream = (MemoryStream)writer.BaseStream; 
    return encoding.GetString(stream.ToArray(), 0, Convert.ToInt32(stream.Length)); 
} 
public T Deserialize(string xml) 
{ 
    UTF8Encoding encoding = new UTF8Encoding(); 
    XmlSerializer serializer = new XmlSerializer(typeof(T)); 
    MemoryStream stream = new MemoryStream(encoding.GetBytes(xml));    
    return (T)serializer.Deserialize(stream); 
} 

Protobuf-NET 바이너리 직렬화 :

public byte[] Serialize(T obj) 
{ 
    byte[] raw; 
    using (MemoryStream memoryStream = new MemoryStream()) 
    { 
    Serializer.Serialize(memoryStream, obj); 
    raw = memoryStream.ToArray(); 
    } 

    return raw;    
} 

public T Deserialize(byte[] serializedType) 
{ 
    T obj; 
    using (MemoryStream memoryStream = new MemoryStream(serializedType)) 
    { 
    obj = Serializer.Deserialize<T>(memoryStream); 
    } 
    return obj; 
} 
+0

레드 게이트 ANTS 프로파일 러 사용을 제안 하겠지만 컴팩트 프레임 워크 (google "red-gate ants profiler compact"검색)와 함께 작동하지 않습니다. – Kane

답변

1

재미있는 ... 생각 :

  • 어떤 버전의 CF입니까? 2.0? 3.5? 당신이 필드 또는 속성 주석을하고 있습니다 특히, CF 3.5 protobuf - 그물
  • CF 2.0 캔보다 훨씬 빠른 속성에 액세스 할 수 있습니다 Delegate.CreateDelegate이있다? 다시, CF에서는 반사 최적화가 제한적입니다. 당신은 내가 사용할 수있는 유일한 옵션은 FieldInfo.SetValue

단순히 CF에 존재하지 않는 다른 것들 중 하나입니다 수있는 필드로, 특성와 CF 3.5 BETER 성능을 얻을 수 있으므로이 몇 군데에서 타협을하기. 지나치게 복잡한 모델의 경우 known issue with the generics limitations of CF도 있습니다. 수정이 진행 중이지만 변경이며 "잠시"복용하고 있습니다.

정보를 위해서는 다양한 형식 (XmlSerializer 및 protobuf-net 포함)을 비교하는 일반 (전체) .NET에 대한 일부 메트릭 are here.

+0

저는 CF2.0을 사용하고 있습니다. 직렬화해야 할 개체의 속성에 특성을 추가했습니다. – Charlie

+0

CF 3.5에서 (CF 3.5 바이너리로) 시도해 볼 수 있습니까? –

+0

좋아요, 저는 CF3.5에서 테스트를 실행하고 CF2에서 상당한 성능 향상을 보았습니다. 바이너리는 직렬화와 비 직렬화 모두에서 훨씬 빠르게 수행됩니다. 불행히도 저는 CF2에 묶여 있습니다. 그렇기 때문에 다시 생각해야 할 수도 있습니다. – Charlie

0

클래스에 대한 사용자 지정 serialization 클래스를 만들려고 했습니까? 범용 직렬 변환기 인 XmlSerializer를 사용하는 대신 (런타임에 여러 클래스를 만듭니다). 이것을하기위한 도구가 있습니다 (sgen). 빌드 프로세스 중에 실행하고 XmlSerializer의 속도로 사용할 수있는 사용자 지정 어셈블리를 생성합니다.

Visual Studio가있는 경우이 옵션은 프로젝트 속성의 작성 탭에서 사용할 수 있습니다.

0

개체를 직렬화하거나 데이터베이스에 쓰는 경우 성능이 저하됩니까? 그 (것)들을 쓰는 것이 느린 저장의 어떤 종류를 명중하기 아마, 나는 serialization 단계보다는 매우 더 중대한 명중 명중다는 것을 생각할 것입니다.

Marc Gravell이 게시 한 perf 측정 값이 1,000,000 회 이상의 성능을 테스트한다는 점에 유의하십시오.

어떤 종류의 데이터베이스를 저장하고 있습니까? 객체가 메모리에 직렬화되었거나 저장소에 곧바로 직렬화됩니까? 어떻게 그들은 DB로 보내지고 있습니까? 얼마나 큰 물건입니까? 하나가 업데이트되면 데이터베이스에 모든 개체를 보내거나 변경된 개체 만 보냅니 까? 메모리에 아무 것도 캐시하지 않거나 매번 저장소에서 다시 읽으십니까?

+0

개체가 SQLCe 데이터베이스에 저장되고 있지만 직렬화와 역 직렬화가 데이터베이스 상호 작용이 아니라 성능 저하라는 것을 분명히 알 수 있습니다. 또한 항목이 메모리에 캐시되고, 하지만 애플 리케이션의 세션 사이에 retreived 수 있도록 DB에 물건을 저장해야합니다. – Charlie

5

나는 이것을 바로 잡을 것입니다. Marc Gravall은 첫 번째 반복에서 모델에 불필요한 오버 헤드가 있으므로 XML 및 바이너리 모두에 대해 직렬화 및 직렬화의 평균 1000 회 반복을 수행하는 테스트를 수행했다고 지적했습니다. . Compact Framework DLL의 v2를 먼저 테스트 한 다음 v3.5 DLL을 사용하여 테스트를 시도했습니다. 여기에 내가 가진 시간이있다. 시간은 ms이다.

.NET 2.0 
================================ XML ====== Binary === 
Serialization 1st Iteration  3236  5508 
Deserialization 1st Iteration 1501  318 
Serialization Average   9.826  5.525 
Deserialization Average   5.525  0.771 

.NET 3.5 
================================ XML ====== Binary === 
Serialization 1st Iteration  3307  5598 
Deserialization 1st Iteration 1386  200 
Serialization Average   10.923  5.605 
Deserialization Average   5.605  0.279 
0

XML은 종종 처리 속도가 느리고 많은 공간을 차지한다. 이 문제를 해결하기 위해 여러 가지 시도가 있었고, 오늘날 가장 인기있는 것은 Open Packaging Convention과 같이 gzip 파일에 많은 것을 버리는 것입니다.

W3C은 gzip 접근 방식이 최적보다 적음을 보여 주었고, 이들과 다양한 other groups은 빠른 처리 및 압축, 전송에 적합한 더 나은 이진 직렬화에 대해 작업 해 왔습니다.

3

방법의 주요 비용은 XmlSerializer 클래스의 실제 생성입니다. serialiser를 만드는 것은 각 객체 유형에 대해 한 번만 수행해야하는 시간 소모적 인 프로세스입니다. 시리얼 라이저를 캐싱하여 성능이 향상되는지 확인하십시오.

이 조언에 이어 나는 XML 직렬화를 계속 사용하도록 허용 한 응용 프로그램에서 큰 성능 향상을 보았습니다.

희망이 도움이됩니다.