2012-02-29 44 views
6

Tôi sử dụng một XmlSerializer để tuần tự hóa/deserialize một số đối tượng. Vấn đề là hiệu suất. Khi lược tả, sử dụng XmlSerializer làm cho ứng dụng của chúng tôi mất thêm 2 giây để bắt đầu. Chúng tôi lưu trữ XmlSerializer của chúng tôi và sử dụng lại chúng. Chúng tôi không thể sử dụng sgen.exe vì chúng tôi đang tạo XmlSerializer với XmlAttributeOverrides.Cải thiện hiệu suất của XmlSerializer

Tôi cố gắng sử dụng thay thế tuần tự hóa như Json.Net và, lúc đầu, nó hoạt động rất tốt. Vấn đề là chúng ta cần phải tương thích ngược để tất cả các xml đã được tạo cần được phân tích cú pháp chính xác. Ngoài ra, đầu ra serialization đối tượng phải là Xml.

Để tóm tắt:

  1. tôi nhận dữ liệu Xml đăng bởi một XmlSerializer.
  2. Tôi cần phải deserialize dữ liệu Xml và chuyển đổi nó thành một đối tượng.
  3. tôi cần phải serialize đối tượng vào Xml (lý tưởng một định dạng XML như một một XmlSerializer sẽ làm)
+0

Dữ liệu XML của bạn chứa thẻ mở '' và thẻ đóng ''. Tôi cho rằng đó là lỗi đánh máy. Hơn nữa trong câu hỏi của bạn, bạn xác định định dạng của dữ liệu đầu vào, nhưng không rõ ràng định nghĩa định dạng của đầu ra JSON. Chính xác như bạn có thể trình bày cùng một thông tin ở định dạng XML khác nhau, bạn có thể tạo ra dữ liệu JSON khác nhau với tập thông tin tương đương, nhưng các định dạng khác nhau. Tôi nghĩ bạn nên xác định rõ hơn định dạng của dữ liệu đầu ra. – Oleg

+0

Sẽ tốt nếu bạn cũng xóa hạn chế "Tôi không thể sử dụng XmlSerializer". Nếu lý do chỉ là hiệu suất, thì có rất nhiều cách để cải thiện hiệu suất, sử dụng sgen.exe hoặc bằng cách thực hiện giao diện 'ISerializable'. Điều gì là không rõ ràng nhất trong câu hỏi: tại sao bạn có định dạng đầu vào rất lạ nếu dữ liệu. Bạn có một tệp XML dài hay bạn có rất nhiều tệp như vậy? Thông thường, người ta có thông tin ban đầu trong cơ sở dữ liệu. Vậy tại sao bạn cần đầu vào XML lạ thay vì truy cập vào dữ liệu * gốc *? – Oleg

+0

Tôi cập nhật câu hỏi của mình để đại diện hơn bởi vấn đề – Melursus

Trả lời

9

Cuối cùng, điều đó tùy thuộc vào độ phức tạp của mô hình của bạn. XmlSerializer cần phải làm rất nhiều suy nghĩ, và thực tế là nó mất quá lâu dẫn tôi nghi ngờ rằng mô hình của bạn là khá phức tạp. Đối với một mô hình đơn giản, có thể thực hiện thủ công việc deserialization bằng cách sử dụng LINQ-to-XML (khá dễ), hoặc thậm chí có thể là XmlReader (nếu bạn cảm thấy rất can đảm - không dễ dàng để có được chính xác 100%) .

Tuy nhiên, nếu mô hình phức tạp, đây là một vấn đề và thẳng thắn sẽ rất nguy hiểm trong việc giới thiệu các lỗi tinh tế.

Tùy chọn khác là DataContractSerializer xử lý xml, nhưng không phải cũng như XmlSerializer và chắc chắn không có nhiều quyền kiểm soát bố cục. Tôi mạnh mẽ nghi ngờ rằng DataContractSerializer sẽ không giúp bạn.

Không có thay thế trực tiếp cho XmlSerializer mà tôi biết, và nếu sgen.exe không phải là một lựa chọn Tôi tin rằng về cơ bản bạn có các tùy chọn:

  • sống với nó
  • viết lại XmlSerializer mình, bằng cách nào đó làm tốt hơn họ
  • sử dụng một cái gì đó giống như LINQ-to-XML và chấp nhận sự nỗ lực tham gia

dài hạn, tôi muốn nói "định dạng chuyển đổi", và sử dụng xml chỉ để nhập trước đây. Tôi tình cờ biết một số giao thức nhị phân rất nhanh có thể thay thế dễ dàng; p

+0

Câu trả lời xuất sắc. Tôi đã phải làm một cái gì đó tương tự trong một dự án mà tôi đã phải sử dụng giao diện và không sử dụng các lớp trừu tượng (kể từ khi C# không làm nhiều thừa kế). Sử dụng LINQ để xml và phản ánh đã làm các trick. Nhiệm vụ tiếp theo của tôi là tạo các thuộc tính thay vì một danh sách các quy tắc trong các tham số (chỉ cần học về điều đó). Tôi phải nói nó rất vui. – pqsk

1

bạn phải Deserialize danh sách của bạn bằng cách sử dụng serialization .net cổ điển

một cái gì đó giống như dưới đây :

TextReader tr = new StreamReader("yourlist.xml"); 
XmlSerializer serializer = new XmlSerializer(typeof(List<YourObject>)); 
List<YourObject> myCutomList = (List<YourObject>)serializer.Deserialize(tr); 
tr.Close(); 

sau đó bạn có thể sử dụng Json.Serialization

JavaScriptSerializer json = new JavaScriptSerializer(); 
JsonResult output = json.Serialize(myCutomList); 
+0

Tôi không thể sử dụng .net XmlSerializer vì trong dự án của chúng tôi, anh ấy có hiệu suất kém. Đó là lý do tại sao tôi cố gắng sử dụng JsonSerializer nhưng tôi cần phải tương thích với định dạng cũ của chúng tôi vì vậy tôi cần phải xử lý Xml serialized bởi XmlSerializer mà không cần sử dụng một XmlSerializer ... – Melursus

0

Nếu bạn có xml được lưu trữ ở định dạng mà bạn không thể sử dụng thì hãy sử dụng xslt để chuyển đổi nó thành định dạng mà bạn có thể sử dụng.

Nếu xml này được lưu trữ ở định dạng XmlSerializer - cho phép nói trong tệp phẳng - hoặc db - thì bạn có thể chạy biến đổi của bạn trên nó một lần và không phải chịu phí XmlSerializer trong thời gian chạy thông thường của bạn.

Hoặc bạn có thể xslt nó tại thời gian chạy - nhưng tôi nghi ngờ rằng điều này sẽ nhanh hơn phương pháp được vạch ra bởi Massimiliano.

0

This câu trả lời có một số thông tin tốt về lý do XmlSerializer chạy chậm với XmlAttributeOverrides.

Bạn có thực sự cần sử dụng XmlSerializer trong chuỗi chính khi khởi động không?

Có thể chạy nó trong chuỗi nền; Nếu chỉ một số phần của dữ liệu là bắt buộc cho khởi động có lẽ bạn có thể tự đọc chúng vào phiên bản proxy/thưa thớt của các lớp thực trong khi XmlSerializer khởi tạo.

Nếu nó là một ứng dụng GUI bạn chỉ có thể thêm một màn hình để ẩn sự chậm trễ (hay một trò chơi của Tetris !!)

Nếu vẫn thất bại, bạn không thể chuyển đổi các tập tin hiện có để JSON bằng cách chỉ cần chạy hiện tại deserialize và một serialize JSON, hoặc là có một yêu cầu khó khăn để giữ cho chúng XML?

0

Bạn có thể sử dụng luồng hoặc tác vụ để ứng dụng khởi động nhanh hơn và không chờ đợi sự phát triển của ổ đĩa cứng hoặc quá trình deserialization.

2

Vấn đề là bạn đang yêu cầu các loại không được bao phủ bởi sgen dẫn đến việc tạo ra các cụm mới trong khi khởi động.

Bạn có thể thử để có được bàn tay của bạn trên các tập tin tạm thời được tạo ra bởi Xmlserializer cho các loại cụ thể của bạn và sử dụng mã này cho lắp ráp xmlserializer pregnerated của riêng bạn. Tôi đã sử dụng approach to find out why csc.exe này đã được thực thi, đã làm chậm quá trình khởi động ứng dụng của tôi.

Bên cạnh đó, nó có thể giúp đổi tên một số loại như trong bài viết để đến cùng tên kiểu mà sgen đang tạo để có thể sử dụng sgen. Thông thường loại mảng không được precreated bởi sgen mà là một pitty đôi khi. Nhưng nếu bạn đặt tên cho lớp của mình là ArrayOf HereGoesYourTypeName thì bạn sẽ có thể sử dụng các cụm được tạo trước.

Các vấn đề liên quan