2009-10-01 44 views
60

Tôi đang tối ưu hóa một đối tượng tùy chỉnh -> tiện ích tuần tự hóa XML, và tất cả đều được thực hiện và hoạt động và đó không phải là vấn đề.Quyết định khi nào nên sử dụng XmlDocument vs XmlReader

Nó hoạt động bằng cách tải tệp vào đối tượng XmlDocument, sau đó đệ quy đi qua tất cả các nút con.

Tôi thấy rằng có lẽ sử dụng XmlReader thay vì có XmlDocument tải/phân tích toàn bộ nội dung sẽ nhanh hơn, vì vậy tôi cũng đã triển khai phiên bản đó.

Các thuật toán hoàn toàn giống nhau, tôi sử dụng lớp trình bao bọc để trừu tượng hóa chức năng xử lý một số XmlNode và số XmlReader. Ví dụ: lợi nhuận của phương thức GetChildren trả về con là XmlNode hoặc SubTree XmlReader.

Vì vậy, tôi đã viết một trình điều khiển thử nghiệm để kiểm tra cả hai phiên bản và sử dụng bộ dữ liệu không tầm thường (tệp XML 900kb với khoảng 1.350 phần tử).

Tuy nhiên, khi sử dụng JetBrains dotTRACE, tôi thấy phiên bản XmlReader thực sự chậm hơn phiên bản XmlDocument! Dường như có một số xử lý quan trọng liên quan đến các cuộc gọi đã đọc XmlReader khi tôi đang lặp qua các nút con.

Vì vậy, tôi nói tất cả những gì để hỏi này:

gì được những ưu điểm/nhược điểm của XmlDocumentXmlReader, và trong hoàn cảnh nào nên bạn sử dụng một trong hai?

Tôi đoán là có ngưỡng kích thước tệp tại đó XmlReader trở nên tiết kiệm hơn về hiệu suất, cũng như ít tốn nhiều bộ nhớ hơn. Tuy nhiên, ngưỡng đó dường như vượt quá 1MB.

Tôi gọi ReadSubTree mỗi thời gian để xử lý các nút con:

public override IEnumerable<IXmlSourceProvider> GetChildren() 
{ 
    XmlReader xr = myXmlSource.ReadSubtree(); 
    // skip past the current element 
    xr.Read(); 

    while (xr.Read()) 
    { 
     if (xr.NodeType != XmlNodeType.Element) continue; 
     yield return new XmlReaderXmlSourceProvider (xr); 
    } 
} 

thử nghiệm đó áp dụng cho rất nhiều đối tượng ở mức duy nhất (tức là rộng & cạn) - nhưng tôi tự hỏi như thế nào XmlReader giá vé khi XML sâu & rộng? I E. XML tôi đang xử lý giống như mô hình đối tượng dữ liệu, 1 đối tượng cha mẹ với nhiều đối tượng con, v.v. 1..M..M..M

Tôi cũng không biết cấu trúc của XML tôi đang phân tích cú pháp, vì vậy tôi có thể không tối ưu hóa cho nó.

+1

Tôi luôn tự hỏi tại sao có cả XmlDocument và XmlReader ... –

+0

Thực tế có một tùy chọn khác cho XMLDocument và XMLReader. Bây giờ bạn có thể sử dụng LINQ to XML nhưng thực ra XMLReader hiệu quả hơn theo nhiều cách. – Tarik

+2

Chờ. Phương thức 'GetChildren' của bạn trả về một' XmlReader'? Bạn có nghĩa là, bạn đang gọi 'XmlReader.Create()' mỗi khi bạn xử lý một nút con? –

Trả lời

63

Tôi thường xem xét nó không phải từ góc nhìn nhanh nhất, nhưng thay vì sử dụng bộ nhớ sử dụng bộ nhớ phối cảnh. Tất cả các triển khai đã đủ nhanh cho các kịch bản sử dụng mà tôi đã sử dụng trong (tích hợp doanh nghiệp điển hình).

Tuy nhiên, nơi tôi đã giảm xuống và đôi khi ngoạn mục, không tính đến kích thước chung của XML mà tôi đang làm việc. Nếu bạn suy nghĩ về nó lên phía trước bạn có thể tiết kiệm cho mình một số đau buồn.

XML có xu hướng phồng lên khi được tải vào bộ nhớ, ít nhất với trình đọc DOM như XmlDocument hoặc XPathDocument. Một cái gì đó như 10: 1? Số lượng chính xác là khó để định lượng, nhưng nếu nó là 1MB trên đĩa, nó sẽ được 10MB trong bộ nhớ, hoặc nhiều hơn, ví dụ.

Một quá trình sử dụng bất kỳ người đọc rằng tải toàn bộ tài liệu vào bộ nhớ một cách trọn vẹn (XmlDocument/XPathDocument) có thể bị từ lớn phân mảnh đối tượng heap, mà cuối cùng có thể dẫn đến OutOfMemoryException s (ngay cả với bộ nhớ còn trống) dẫn đến một dịch vụ không có sẵn /quá trình.

Vì các đối tượng có kích thước lớn hơn 85K kết thúc trên vùng đối tượng lớn và bạn có vụ nổ kích thước 10: 1 với trình đọc DOM, bạn có thể thấy nó không mất nhiều thời gian Các tài liệu XML đang được phân bổ từ đống đối tượng lớn.

XmlDocument rất dễ sử dụng. Hạn chế thực sự duy nhất của nó là nó tải toàn bộ tài liệu XML vào bộ nhớ để xử lý. Dễ sử dụng của nó.

XmlReader là trình đọc dựa trên luồng để giữ cho quá trình sử dụng bộ nhớ của bạn trở nên phẳng hơn nhưng khó sử dụng hơn.

XPathDocument có xu hướng là phiên bản XmlDocument nhanh hơn, chỉ đọc, nhưng vẫn bị bộ nhớ 'sưng lên'.

+4

Tải các tài liệu XML, tuy nhiên lớn, vào bộ nhớ KHÔNG gây ra các đối tượng lớn. Tuy nhiên, giữ XML như một chuỗi ký tự! Nó là kích thước của các đối tượng riêng lẻ quan trọng đối với khả năng của GC để chống phân mảnh bộ nhớ, nhưng tổng kích thước của đồ thị đối tượng quan trọng đối với việc sử dụng bộ nhớ. –

+1

FWIW Tôi vừa làm một điểm chuẩn giữa XDocument, XMLReader và XmlDocument. Để thực hiện các đường dẫn tương tự, chúng mất 0,004, 0,001 và 0,692 giây tương ứng. – micahhoover

0

Có ngưỡng kích thước mà tại đó XmlDocument trở nên chậm hơn và cuối cùng không sử dụng được. Nhưng giá trị thực tế của ngưỡng sẽ phụ thuộc vào ứng dụng của bạn và nội dung XML, vì vậy không có quy tắc cứng và nhanh nào.

Nếu tệp XML của bạn có thể chứa danh sách lớn (nói hàng chục nghìn phần tử), bạn chắc chắn nên sử dụng XmlReader.

9

XmlDocument là bản trình bày trong bộ nhớ của toàn bộ tài liệu XML. Do đó nếu tài liệu của bạn lớn, thì nó sẽ tiêu tốn nhiều bộ nhớ hơn nếu bạn đã đọc nó bằng XmlReader.

Giả sử rằng khi bạn sử dụng XmlReader, bạn đọc và xử lý từng phần tử rồi loại bỏ nó.Nếu bạn sử dụng XmlReader và xây dựng một cấu trúc trung gian khác trong bộ nhớ thì bạn có cùng một vấn đề, và bạn đang đánh bại mục đích của nó.

Google cho "SAX versus DOM" để đọc thêm về sự khác biệt giữa hai mô hình xử lý XML.

+1

Điều gây phiền nhiễu là có hoàn toàn không có chỉ dẫn ở tất cả các nơi (ballpark) một tài liệu trở thành "lớn" và XmlReader bắt đầu mang lại bất kỳ lợi ích đáng kể kích thước. Có 1KB, 1MB hoặc thậm chí nhiều hơn không? Tôi chắc rằng câu trả lời là "nó phụ thuộc", nhưng không có manh mối nào cả, chúng tôi còn lại để xác định những điều này theo từng trường hợp, trừ trường hợp có thể xử lý dữ liệu lớn tùy ý (sau đó XmlReader là sự lựa chọn rõ ràng). –

0

Sự khác biệt về mã hóa là do hai phép đo khác nhau đang được trộn lẫn. UTF-32 yêu cầu 4 byte cho mỗi ký tự, và vốn đã chậm hơn so với dữ liệu byte đơn.

Nếu bạn nhìn vào thử nghiệm phần tử lớn (100K), bạn sẽ thấy thời gian tăng khoảng 70mS cho mỗi trường hợp bất kể phương thức tải được sử dụng.

Đây là một (gần) chênh lệch liên tục gây ra đặc biệt bởi mỗi nhân vật trên cao,

4

xem xét khác là XMLReader có thể mạnh mẽ hơn để xử lý ít hơn một cách hoàn hảo được tạo hình XML. Gần đây tôi đã tạo một ứng dụng khách đã tiêu thụ một luồng XML, nhưng luồng không có các ký tự đặc biệt được thoát đúng trong các URI chứa trong một số phần tử. XMLDocument và XPathDocument từ chối tải XML tất cả, trong khi sử dụng XMLReader tôi có thể trích xuất thông tin tôi cần từ luồng.

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