2012-06-10 28 views
5

Tôi có hai ứng dụng .NET chạy độc lập (có thể bắt đầu theo thứ tự bất kỳ hoặc chỉ có thể chạy) sử dụng XML làm kho dữ liệu. Vì vậy, cả hai ứng dụng có thể đọc và ghi vào tệp XML. Để giữ cho dữ liệu được cập nhật, tôi đang tải tệp XML mỗi lần từ đĩa trước khi đọc và ghi các hoạt động. Và tôi đang sử dụng truy vấn XPath để truy vấn nút cụ thể. Bây giờ có vấn đề hiệu năng được quan sát trong phương pháp này vì có yêu cầu đọc và ghi trên XML mỗi giây từ một ứng dụng (sử dụng bỏ phiếu và không thể thay đổi) Tôi không chắc chính xác điều gì đang gây ra hiệu suất, nhưng tôi tin đọc liên tục của nó viết.Làm thế nào để cải thiện hiệu suất ghi đọc XML

Tôi đã thử sử dụng các tệp được ánh xạ bộ nhớ từ .NET 4.0 nhưng tôi bị hạn chế sử dụng .NET 3.5 và không phải là phiên bản cao hơn.

Có ai có thể giúp tôi về điều này không?

Lưu ý: Các nút XML có một số thuộc tính phổ biến, số thuộc tính khác nhau và một ID mà tôi sử dụng để truy vấn XPath.

+3

Bạn có chắc chắn không thể triển khai nguồn dữ liệu khác như Sql Server Compact không? Tại sao bạn không thể thay đổi nó? – rcdmk

+0

Bạn có cân nhắc sử dụng thứ gì đó khác với xml cho mục đích sử dụng đó không? có thể memcached (http://memcached.org/)? sql? nếu bạn phải sử dụng xml, hãy thử sử dụng XmlReader và XmlWriter – eyossi

+4

Nếu bạn không thể thay đổi ứng dụng đầu tiên, các tùy chọn của bạn rất hạn chế. Thiết kế xấu dẫn đến hiệu suất kém. – Filip

Trả lời

1

Thử mở tệp độc quyền. Ứng dụng khác có thể bị lỗi, nhưng nếu nó không sụp đổ, bạn sẽ biết một điều chắc chắn: nó không thể gọi nhiều I/O tải trong một chu kỳ trên tệp được chia sẻ, bởi vì tất cả các lần truy cập của nó sẽ thất bại ngay lập tức.

Hy vọng rằng nó sẽ chỉ chờ một giây và thử lại, và điều đó sẽ hoạt động tốt cho bạn.

using (Stream iStream = File.Open("myfile.xml", 
      FileMode.Open, FileAccess.ReadWrite, FileShare.None)) 
{ 
    ... 
} 
2

XML không được thiết kế để truy vấn nặng. Nếu bạn cần làm điều này, hãy xem xét sử dụng một cơ sở dữ liệu. SQL Server Compact có thể là một lựa chọn tốt. Nếu bạn cần phải gắn bó với XML mặc dù và cần phải làm việc với các tệp lớn và cần hiệu suất xem xét sử dụng XmlReader/XmlWriter mà không tải toàn bộ tệp vào bộ nhớ và khá nhanh.

+1

-1: Nếu chúng không thể thay đổi ứng dụng, cơ sở dữ liệu có thể trợ giúp như thế nào? –

+0

Thật vậy, tôi không nhận thấy ràng buộc này. XmlReader/XmlWriter như đã đề cập trong câu trả lời của tôi là cách để đi trong trường hợp này. –

3

NẾU bạn chắc chắn rằng hiệu suất truy cập đến từ I/O và bạn không thể thay đổi cả hai ứng dụng thực sự là một chút bạn có thể làm.

Giải pháp đầu tiên không thay đổi mã ứng dụng hiện tại: sử dụng RAM disk. Nếu họ đang sử dụng tệp đó làm bộ nhớ dùng chung, bạn có thể thực hiện việc này mà không cần bất kỳ thay đổi nào khác. Nếu dữ liệu liên tục, bạn có thể cần thực hiện một bản sao nền cho một phương tiện khác sau mỗi lần viết. Hiệu suất sẽ không tốt bằng bộ nhớ chia sẻ thực sự nhưng ít nhất bạn sẽ không phải chờ các hoạt động I/O chậm.

Giải pháp thứ hai chỉ có thay đổi trong ứng dụng phải đọc dữ liệu: thường phân tích cú pháp tệp XML khá chậm (đặc biệt nếu bạn đang sử dụng XmlDocument và tệp không quá ít). Trong trường hợp này, sử dụng XmlReader, bạn phải làm cho mã đọc của bạn phức tạp hơn và quên đi các truy vấn XPath nhưng hiệu suất của nó sẽ tốt hơn nhiều lần so với XmlDocument và nó sẽ không làm chậm kích thước tệp.

Cập nhật nhỏ (hoặc không quá nhỏ): nếu mã của ứng dụng thứ hai (tôi đoán tệp sẽ đọc tệp) có thể thay đổi, bạn có thể làm một chút để cải thiện hiệu suất của nó. Trước hết không đọc từng tập tin. Kiểm tra dấu thời gian của nó, đăng ký FileSystemWatcher cho tệp đó hoặc bất kỳ tệp nào khác nhưng không đọc/phân tích tệp mỗi lần. Khi bạn thực hiện việc này, bạn có thể tiến lên một bước: chỉ đọc/phân tích cú pháp tệp khi nó thay đổi, chuẩn bị XmlDocument trên nền (một chủ đề khác) và làm cho nó sẵn sàng cho các yêu cầu bỏ phiếu.Nếu các yêu cầu là cách nhau, chúng thậm chí có thể thấy thời gian phản hồi rất nhanh (nhưng hiệu suất hồ sơ của truy vấn XPath XmlDocument đối với tệp thông thường của bạn).

EDIT: here bạn có thể tìm thấy đĩa RAM do Microsoft cung cấp. Nó khá đơn giản và ngây thơ nhưng thường là bạn/chúng tôi không cần nhiều hơn thế. Hơn nữa nó là một ví dụ về DDK, do đó bạn sẽ nhận được mã nguồn quá (trong trường hợp này ... chỉ để cho vui).

+0

+1 - Đĩa RAM là một trong số ít những thứ mà người ta có thể làm với một ứng dụng được thiết kế sai, bất kể nó được thiết kế kém như thế nào. –

+0

Bằng đĩa RAM, bạn có nghĩa là tệp được chia sẻ/tệp trong bộ nhớ không? – user1447725

+0

Không, đĩa RAM là một đĩa ảo nằm trong bộ nhớ. Ứng dụng sẽ xem như một ổ đĩa bình thường (thêm một liên kết). –

2

Thay vì đọc tệp XML rất thời gian, chỉ cần đọc nó lần đầu tiên và cũng có được thời gian sửa đổi cuối cùng cho tệp.

Khi bạn cần biết liệu dữ liệu có cập nhật hay không, chỉ cần kiểm tra thời gian đã sửa đổi của tệp và chỉ đọc lại tệp nếu tệp thực sự đã thay đổi.

+0

Nếu ứng dụng đó * thực sự * ghi vào tệp mỗi giây, điều này sẽ không giúp được gì nhiều. Nhưng điều này có thể dễ dàng kiểm tra trước khi viết mã như vậy. –

2

Đừng thăm dò ý kiến ​​của tệp. Đọc nó một lần và giữ nó trong bộ nhớ, sau đó sử dụng FileSystemWatcher để tải lại nó chỉ khi thay đổi.

Hoặc cách khác, đọc dấu thời gian sửa đổi và chỉ tải lại tệp nếu dấu thời gian thay đổi.


Ngoài ra, khi đọc tệp, hãy đảm bảo khóa không độc quyền để những người đọc khác không bị chặn.

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