Linq to Xml,保持 XDocument 加载吗?
假设我正在制作一个 WinForms 程序,它将在幕后使用 XML 文档作为持久机制...
以下两种方法的优缺点是什么...
在每个方法调用中加载 XDocument:
公共类 XmlFoosRepository { 字符串 xml 文件名; 公共 XmlFoosRepository(字符串 xmlFileName) { this.xmlFileName = xmlFileName; } 公共 int AddFoo(Foo foo) { var xDoc = XDocument.Load(xmlFileName); // 始终调用 Load() // ... xDoc.Save(xmlFileName); 返回 foo.ID; } public IEnumerable
;获取Foos() { var xDoc = XDocument.Load(xmlFileName); // 始终调用 Load() // ... 返回 foos; } }
或
将 XDocument 保留在内存中...
公共类 XmlFoosRepository { XDocument xDoc; 公共 XmlFoosRepository(字符串 xmlFileName) { xDoc = XDocument.Load(xmlFileName); // 现在在内存中 } 公共 int AddFoo(Foo foo) { // ... xDoc.Save(xmlFileName); 返回 foo.ID; } public IEnumerable
;获取Foos() { // ... 返回 foos; } }
Let's say I'm making a WinForms program that will use an XML document behind the scenes as a persistence mechanism...
What are the pros/cons to the two following approaches...
Load the XDocument in each method call:
public class XmlFoosRepository { string xmlFileName; public XmlFoosRepository(string xmlFileName) { this.xmlFileName = xmlFileName; } public int AddFoo(Foo foo) { var xDoc = XDocument.Load(xmlFileName); // Always call Load() // ... xDoc.Save(xmlFileName); return foo.ID; } public IEnumerable<Foo> GetFoos() { var xDoc = XDocument.Load(xmlFileName); // Always call Load() // ... return foos; } }
or
Keep the XDocument in memory...
public class XmlFoosRepository { XDocument xDoc; public XmlFoosRepository(string xmlFileName) { xDoc = XDocument.Load(xmlFileName); // Now in memory } public int AddFoo(Foo foo) { // ... xDoc.Save(xmlFileName); return foo.ID; } public IEnumerable<Foo> GetFoos() { // ... return foos; } }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
基于文件的优点:
- 跨流程运行良好(如果需要)
- 保持较小的持续内存需求(如果文件很大,例如超过 10mb)
基于文件的缺点:
- 每次操作加载速度较慢
基于内存的优点:
- 更快,无需一次又一次重新序列化的开销
- 如果您稍后需要通过 Web 服务等访问文件,则更容易移植。
基于内存的缺点:
- 持续的内存需求(如果文件很大)
另一个想法是,如果您已经有了 XML 格式的数据,为什么不直接将其用作 POCO 对象,而是将它们重新序列化为“GetFoos”方法中的对象。
File Based Pros:
- Works well across processes (if required)
- Keeps on-going memory requirements small (if the file is large, like over 10mb)
File Based Cons:
- Slower to load on each operation
Memory Based Pros:
- Faster, no overhead to re-serialize again and again
- Easier to port, if you need to access the file later via a Web Service, etc.
Memory Based Cons:
- On-going memory requirements (if large file)
Another thought, if you have your data in XML already, why not just use that as your POCO objects, instead re-serializing them into objects in your "GetFoos" method.
第一个似乎效率稍低,因为每次访问 XML 文档时都加载它,但您却一无所获。使用选项 1,您必须先访问磁盘,并将 XML 文件加载到内存中,然后才能访问它。访问磁盘是现代计算机上执行成本最高的操作之一,应尽可能避免。
话虽这么说,如果 XML 文件太大,内存占用量非常大,那么您可能只想加载它一小段时间。但是,如果内存占用量很大,那么您可能需要研究一种不同的持久数据方式,这种方式不需要您立即加载整个文档来进行修改。
The first one just seems slightly inefficient as you gain nothing by loading the XML document every time you access it. With option 1 you have to go to disk, and load the XML file into memory, before accessing it. Going to the disk is one of the most costly operations you can perform with a modern computer, and should be avoided as much as possible.
That being said, if the XML file is that large that the memory footprint is incredibly significant then you may want to only have it loaded for small amounts of time. However, if the memory footprint is that large then you might want to look into a different way of persisting data that doesn't require you to load the whole document at once to make modifications.
平衡主要在内存和文件系统访问之间 - 如果您要在代码中大量使用该文档,您不希望与文件系统的交互超出您的预期......但如果很少访问它而且巨大,您可能不希望内存受到影响。
我可能默认将其保留在内存中 - 当它变得足够大以至于内存占用很重要时,您可能无论如何都不想使用 XML。
除了这些方面之外,在两种情况下,您都需要考虑特定应用程序所需的线程模型。
正如数据点之一 - 我在 C# in Depth 网站上使用第二种模式进行勘误等,并且效果非常好。
The balance is mostly between memory and file system access - if you're going to use the document a lot within your code, you don't want to be interacting with the file system more than you want... but if it's rarely accessed and huge, you may not want the memory hit.
I would probably default to keeping it in memory - by the time it gets sufficiently big that the memory hit is important, you may not want to use XML anyway.
Aside from these aspects, in both cases you will need to consider the threading model required by your particular application.
Just as one point of data - I use the second pattern on the C# in Depth web site for errata etc, and it works very well.
将文档存储在内存中的一个可能的缺点是,如果您没有降级缓存,那么这些实例可能会永远存在。这不一定是一件可怕的事情,但您应该在设计中考虑这一点。
此外,如果文档很大,或者有大量小文档,缓存中的项目数量可能会导致内存问题。同样,您必须衡量这是否是您所关心的问题。
也就是说,您肯定会从缓存中获益;根据文档以及您访问它的频率,您不必将文档处理为
XDocument
重复。如果文档很大,或者您要多次访问它们,那么您可以节省处理时间,因为您已经完成了一次,并且不必再次执行。A possible drawback of storing the documents in memory is that if you don't have a degrading cache, then those instances will potentially live forever. This isn't necessarily a horrible thing but it's something you should think about in your design.
Also, the number of items in the cache, if the documents are large, or you have a tremendous number of little documents, could cause memory issues. Again, you have to measure whether or not this is a concern for you.
That said, you definitely gain a benefit from the cache; depending on the document and how often you access it, you won't have to process the document into an
XDocument
repeatedly. If the documents are large, or you are accessing them many times, then you save on that processing time as you've done it once, and won't have to do it again.