2009-07-07 8 views
8

Tôi đang làm việc trên một ứng dụng khung nhỏ gọn và cần tăng hiệu suất. Ứng dụng hiện hoạt động ngoại tuyến bằng cách tuần tự hóa các đối tượng vào XML và lưu trữ chúng trong cơ sở dữ liệu. Sử dụng công cụ lược tả tôi có thể thấy đây là một chi phí khá lớn, làm chậm ứng dụng. Tôi nghĩ nếu tôi chuyển sang một serialization nhị phân hiệu suất sẽ tăng lên, nhưng bởi vì điều này không được hỗ trợ trong khuôn khổ nhỏ gọn, tôi nhìn vào protobuf-net. Việc serialization có vẻ nhanh hơn, nhưng deserialization chậm hơn nhiều và các ứng dụng đang làm nhiều deserializing hơn serializing.XML so với hiệu suất nhị phân để tuần tự hóa/Deserialization

Nếu chuỗi tuần tự hóa nhị phân phải nhanh hơn và nếu có thì tôi có thể làm gì để tăng tốc hiệu suất? Dưới đây là một đoạn như thế nào Tôi đang sử dụng cả XML và nhị phân:

serialization 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 Binary serialization:

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

Tôi sẽ đề xuất sử dụng trình thu thập thông tin Red-Gate ANTS nhưng không hoạt động với khung Compact (tìm kiếm trên google "kiến trúc nhỏ gọn của cổng đỏ") – Kane

Trả lời

1

Thú vị ... suy nghĩ:

  • phiên bản CF này là gì; 2.0? 3.5? Cụ thể, CF 3.5 có Delegate.CreateDelegate cho phép protobuf-net truy cập các thuộc tính nhanh hơn nhiều so với trong CF 2.0
  • bạn có chú thích các trường hoặc thuộc tính? Một lần nữa, trong CF các tối ưu hóa phản xạ bị hạn chế; bạn có thể có được hiệu suất beter trong CF 3.5 với tính, như với một lĩnh vực lựa chọn duy nhất tôi có sẵn là FieldInfo.SetValue

Có một số thứ khác mà chỉ đơn giản là không tồn tại trong CF, vì vậy nó có để thỏa hiệp ở một vài nơi. Đối với các mô hình quá phức tạp, cũng có một số known issue with the generics limitations of CF. Sửa chữa đang được tiến hành, nhưng đây là thay đổi lớn và đang thực hiện "một thời gian".

Để biết thông tin, một số chỉ số về định dạng (đầy đủ) .NET so sánh các định dạng khác nhau (bao gồm XmlSerializer và protobuf-net) are here.

+0

Tôi đang sử dụng CF2.0 và tôi đã thêm các thuộc tính vào các thuộc tính cho các đối tượng mà tôi cần để tuần tự hóa. – Charlie

+0

Có thể thử nó trong CF 3.5 (với CF 3.5 nhị phân) chỉ để xem nếu nó sửa chữa nó? –

+0

Ok, tôi vừa chạy thử nghiệm của tôi trên CF3.5 và thấy hiệu suất tăng đáng kể từ CF2; nhị phân thực hiện nhanh hơn rất nhiều cho cả serialization và deserialization. Thật không may tôi đang gắn với CF2 mặc dù vậy có thể phải suy nghĩ lại mọi thứ. – Charlie

0

Bạn đã thử tạo các lớp serialization tùy chỉnh cho lớp học của mình chưa? Thay vì sử dụng XmlSerializer mà là một serializer mục đích chung (nó tạo ra một loạt các lớp tại thời gian chạy). Có một công cụ để làm điều này (sgen). Bạn chạy nó trong quá trình xây dựng của bạn và nó tạo ra một hội đồng tùy chỉnh có thể được sử dụng trong tốc độ của XmlSerializer.

Nếu bạn có Visual Studio, tùy chọn có sẵn trong tab Xây dựng của thuộc tính dự án của bạn.

0

Lần truy cập có hiệu suất trong việc tuần tự hóa các đối tượng hay viết chúng vào cơ sở dữ liệu không? Kể từ khi viết chúng có khả năng nhấn một số loại lưu trữ chậm, tôi tưởng tượng nó là một hit perf lớn hơn nhiều so với bước serialization.

Hãy nhớ rằng các phép đo perf được Marc Gravell đăng tải đang thử nghiệm hiệu suất trên 1.000.000 lần lặp.

Bạn lưu trữ loại cơ sở dữ liệu nào? Các đối tượng có được tuần tự hóa trong bộ nhớ hoặc thẳng vào bộ nhớ không? Chúng được gửi tới db như thế nào? Các vật thể lớn cỡ nào? Khi một cập nhật, bạn có gửi tất cả các đối tượng đến cơ sở dữ liệu hay chỉ một đối tượng đã thay đổi không? Bạn đang lưu vào bộ nhớ đệm bất cứ thứ gì trong bộ nhớ, hay đọc lại từ bộ nhớ mỗi lần?

+0

Các đối tượng đang được lưu trữ trong cơ sở dữ liệu SQLCe, nhưng tôi có thể thấy rõ rằng việc tuần tự hóa và deserialization là hiệu suất hit, chứ không phải là tương tác cơ sở dữ liệu. nhưng cần lưu trữ nội dung trong DB để có thể truy xuất lại giữa các phiên của ứng dụng. – Charlie

5

Tôi sẽ sửa bản thân mình về điều này, Marc Gravall đã chỉ ra lần lặp đầu tiên có chi phí cho mô hình. Vì vậy, tôi đã thực hiện một số thử nghiệm lấy trung bình 1000 lần lặp và tuần tự hóa cho cả XML và nhị phân . Tôi đã thử nghiệm của tôi với v2 của Compact Framework DLL đầu tiên, và sau đó với v3.5 DLL. Dưới đây là những gì tôi nhận được, thời gian bằng 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 thường xử lý chậm và chiếm nhiều không gian. Đã có một số nỗ lực khác nhau để giải quyết vấn đề này và phổ biến nhất hiện nay dường như chỉ là giảm số lượng lớn trong tệp gzip, như với số Open Packaging Convention.

W3C đã cho thấy cách tiếp cận gzip ít hơn tối ưu, và chúng và khác nhau other groups đã làm việc trên một chuỗi tuần tự hóa tốt hơn phù hợp để xử lý và nén nhanh, để truyền.

3

Chi phí chính trong phương thức của bạn là tạo ra lớp XmlSerializer thực tế. Tạo serialiser là một quá trình tốn thời gian mà bạn chỉ nên thực hiện một lần cho mỗi kiểu đối tượng. Hãy thử bộ nhớ đệm các serialisers và xem nếu điều đó cải thiện hiệu suất ở tất cả.

Làm theo lời khuyên này tôi đã thấy một cải tiến hiệu suất lớn trong ứng dụng của mình cho phép tôi tiếp tục sử dụng tuần tự hóa XML.

Hy vọng điều này sẽ hữu ích.