C# 存储许多小对象的高效内存方法

C# 存储许多小对象的高效内存方法,c#,design-patterns,C#,Design Patterns,我有一个简单的Person类,有4个字符串和整数 public class Person { public string FirstName { get; set; } public string LastName { get; set; } public int Age { get; set; } public string PostalCode { get; set; } } 我们需要在内存中存储大量这些数据。集合需要通过任何

我有一个简单的
Person
类,有4个字符串和整数

public class Person
{
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public string PostalCode { get; set; }
}
我们需要在内存中存储大量这些数据。集合需要通过任何字段进行搜索。项目将作为生命周期的一部分添加和删除


Flyweight模式似乎不起作用,因为在对象上没有大量重复值,只有在字段级别。什么样的模式或策略最能限制内存开销并发挥良好的性能?

这里可能需要多种方法的结合。。。首先,最好将其保留为引用类型,以便在搜索时不会到处复制结构。使用
string.Intern(string)
可以减少重复的名字和姓氏以及邮政编码的内存使用。。。最后使用
字典
按值索引这些条目。。。在FirstName的情况下,
TKey
可能是字符串,
TValue
List
,这样您就可以通过所述字符串查找人员。。。这称为反向索引:-字典的另一种替代方法是实现您自己的树或Trie结构,例如前缀Trie。。。您可以用O(logn)速度换取比O(1)字典更少的内存

就在内存中存储大量数据而言,这取决于大量数据是什么。。。但最终你要有足够的内存来处理它们。。。或者开始扩展到分布式系统,以共享对象,例如MapReduce模式,或者在磁盘上“分页”

我们需要在内存中存储大量这些数据

那么一个数组
Person[]
将是最简单的方法,但是
列表
将更接近,并且更易于使用。只需确保通过使用容量参数最小化重新分配

集合需要通过任何字段进行搜索

简单,
。其中(p=>p.FirstName==value)


用字典加速会消耗内存。

多少是“多少”?你有几十万,几百万,几十亿,更多吗?内存很便宜;大多数人都有很多。如果你说的是数百万或更少,只要做最简单的事情,你可能不需要担心减少内存占用。如果你有更多的内存,你可能想把它们都放在数据库中,而不想在C#程序中一次把它们都放在内存中。我不同意大多数人都有很多内存或者能够升级到很多。我们的目标客户PC中有很大一部分充其量只有几台Gig,在64位的.NET应用程序中进行数字运算很容易就完成了。当然,这都是相对的。字符串有多长?我建议研究对象数据库,其中许多支持“内存”模式。基本上,您的需求(紧凑的大小、搜索能力、对大量实例的支持)都由数据库解决。尤其是对象数据库,它会自动处理元数据,这样您就不必担心手动定义表了。@user2547359这样您就不会有问题了。这实际上不会占用那么多内存。做你觉得最简单的事,看看你有没有问题。如果你这样做了,发布一些更详细的信息(你是否遇到了错误,速度是否慢,实际使用了多少内存,以及你希望得到的结果是什么,等等)。如果你没有问题,那么很好,你就完成了。由于所述数组的顺序内存分配和相关碎片,可能会比链表或其他结构更快地耗尽内存,不是吗?帖子将表明他正在试图找到使用更少内存的方法,例如,与其在一百万个项目中存储20年,不如先存储20年,然后再存储一百万个没有年龄属性的项目,或者类似的东西。从理论上讲,如果存在大量重复,类似的内容可能会带来净收益,但这会很复杂。@Servy:a
Age
属性将是一个坏例子(太小)。您可能可以在某些字符串上保存一些内容(重复的名称很常见)。@HenkHolterman,这就是我没有回答的原因。如果他确实拥有如此多的数据,以至于这些问题都是相关的,那么我认为数据库绝对是最好的选择。重新实现DBs拥有的所有大型数据管理技术将是一项繁重的工作,但没有真正的回报。@DavidH链表将消耗大约两倍的总内存,即使它不需要按顺序进行。有很多更简单的方法来处理这个问题,而不会使内存翻倍。基本上,如果您有一个具有这么多值的单个数组,那么您需要创建一个具有数组列表的新类,每个内部数组都是一些设置的批处理大小(可能是几十万),然后让类的索引器将其公开,就好像数据是连续的一样。这将内存拆分为更小的卡盘,开销比LL小得多。关键是OP希望减少内存。字典以牺牲记忆换取速度。如果你的内存非常有限,你就不能这样做,你需要牺牲速度来换取内存。@DavidH-OP没有要求O(1),但要求内存效率。+1,因为他们联合起来对付你。它们的数组答案将减少内存使用,但如果管理得不好可能会很糟糕,因为可能会将LOH钉死,因此如果没有指定某些条件,这也不是一个特别好的答案。此外,通过消除重复项来管理字符串可能比使用字典有更大的影响。例如,如果存在大量重复,一种方法可能是将字符串放在字典中,并使用它们的哈希从数组中的索引引用它们,这可能会提高效率和内存使用。这一切都取决于数据。@JasonWilliams-你认为字典里有什么?大阵列…其中两个。一个用于哈希桶,一个用于条目