C# 将数据存储在内存中,哪种方法是好的?
我有一个items.xml文件,一旦应用程序启动,它就会加载到内存中。 xml中的每个元素都“转换”为类型C# 将数据存储在内存中,哪种方法是好的?,c#,.net,memory,C#,.net,Memory,我有一个items.xml文件,一旦应用程序启动,它就会加载到内存中。 xml中的每个元素都“转换”为类型Item(只有很少的int和string属性),然后添加到项目列表中。项目列表应包含数千个项目的实例 将数据存储在对象中(Itemclass,在我的示例中)可以吗?是否有其他方法将此类数据存储在内存中?这很好,您将使用一种或另一种类型的对象,因此自定义对象是一个不错的选择 还有其他加载和查询XML数据的方法,例如使用和查询XML数据。在不确切知道这些项对象用于什么的情况下,我不能确定,但您所
Item
(只有很少的int和string属性),然后添加到项目列表中。项目列表应包含数千个项目的实例
将数据存储在对象中(Item
class,在我的示例中)可以吗?是否有其他方法将此类数据存储在内存中?这很好,您将使用一种或另一种类型的对象,因此自定义对象是一个不错的选择
还有其他加载和查询XML数据的方法,例如使用和查询XML数据。在不确切知道这些项
对象用于什么的情况下,我不能确定,但您所描述的听起来很好
如果这些对象中有100000个(而不是1000个),那么列表就不是最好的数据结构。这有两种方法。要么把它作为一个列表,当它成为一个问题时再处理它,要么现在就解决它
前者意味着您现在没有工作要做,但将来有未知数量的工作要做——以后数据结构的更改将有更多的潜在影响(需要更改的代码越多,可能会引入错误)
后者意味着现在已知的工作量,但(希望)在将来没有工作,因为您选择了一个可扩展的数据结构。然而,要小心过早的优化。如果你的列表从未超过当前大小,那么你做这项工作毫无收获。这很好,只要你确保不消耗所有内存就可以了。我已经为复杂的系统做了这项工作
如果列表中的索引以外的其他对象定期访问您的数据,则可能需要使用字典对该项进行索引,例如:
Dictionary<string, Item> lookup =
list.ToDictionary(x => x.Code);
还有,;如果许多字符串值重复出现,您可以通过编写自己的interner来节省一些空间
Dictionary<string,string> interner =
new Dictionary<string,string>();
foreach(Item item in list) {
string s, name = item.Name;
if(interner.TryGetValue(name, out s))
item.Name = s;
else
interner.Add(name, name);
}
Dictionary interner=
新字典();
foreach(列表中的项目){
字符串s,name=item.name;
if(内部TryGetValue(名称,输出)
项目名称=s;
其他的
添加(名称、名称);
}
只保留并重新使用唯一的字符串,这将减少内存使用。首先要担心功能是否正确。第二,担心性能。分析应用程序并查看它在性能方面的影响。它可能永远不会出现在您的配置中。但是,如果您在这方面遇到性能问题,请尝试为单个项或子项发明键。通过这种方式,您可以使用键和项(或项列表)填充一个或多个字典,从而减少对相关项的访问时间
请记住,这些查找字典“便宜”,因为它们只存储对项目的引用,而不是对象的副本。项目列表是只读的,还是需要处理修改?如果它是只读的,那么到目前为止每个人的建议都是可以接受的。如果内存中的对象是可修改的,那么还有很多问题没有回答
如果您要处理修改,您将如何:
…处理并发访问
…是否将项目列表同步回XML文档
…如果有人修改基础XML文档,是否会使内存缓存过期
…确保应用程序崩溃/重新启动时不会丢失数据
使用内存中的对象进行快速访问是一种很好的做法,我一直都是自己这么做的。但是,如果您的数据不稳定,这不是一个简单的解决方案。在这种情况下,您应该使用符合ACID标准的数据库。声誉意味着什么。。。回答得好,卡洛+有时我认为表演就是一切。。。谢谢你提醒我,好方法!在ram上使用cpu:)@Zippo好吧,毕竟你只做一次。不妨把它整理一下。
Dictionary<string,string> interner =
new Dictionary<string,string>();
foreach(Item item in list) {
string s, name = item.Name;
if(interner.TryGetValue(name, out s))
item.Name = s;
else
interner.Add(name, name);
}