Seb*_*son 10 c# optimization performance memory-management in-memory
我需要能够在 C# 中搜索大约 200 万个项目的集合。应该可以在多个字段上进行搜索。简单的字符串匹配就足够了。
使用像数据库这样的外部依赖不是一种选择,但使用内存数据库就可以了。
主要目标是做到这一点内存高效。
集合中的类型非常简单,没有长字符串:
public class Item
{
public string Name { get; set; } // Around 50 chars
public string Category { get; set; } // Around 20 chars
public bool IsActive { get; set; }
public DateTimeOffset CreatedAt { get; set; }
public IReadOnlyList<string> Tags { get; set; } // 2-3 items
}
Run Code Online (Sandbox Code Playgroud)
明确重点和要求:
使用简单List<T>的上述类型,无论是作为 aclass还是 a struct,仍然需要大约 2 GB 的内存。
有没有更好的办法?
类中最重要的内存占用是使用只读列表。去掉它,你会减少大约 60% 的内存占用(用三个标签测试):
public class Item
{
public string Name { get; set; }
public string Category { get; set; }
public bool IsActive { get; set; }
public DateTimeOffset CreatedAt { get; set; }
public string Tags { get; set; } // Semi-colon separated
}
Run Code Online (Sandbox Code Playgroud)
另外,请考虑使用DateTime代替DateTimeOffset. 这将进一步减少大约 10% 的内存占用。
小智 1
你可以做这些点,然后你就会看到是否有问题:
您可以启用gcAllowVeryLargeObjects以启用大于 2 GB 的数组。
让类执行。当您在类和结构之间进行选择时,性能并不是主要因素。我认为没有理由在这里使用 struct 。请参阅在类和结构之间进行选择。
根据您的搜索过滤器,您必须覆盖 GetHashCode 和 Equal。
您是否需要改变属性,或者只是在集合中搜索对象?
如果您只是想进行研究,并且您的属性经常重复出现,那么您可以让一个属性被许多对象使用。
这样,值只存储一次,对象只存储引用。
仅当您不想改变属性时才可以执行此操作。
例如,如果两个对象具有相同的类别:
public class Category
{
public string Value { get; }
public Category(string category)
{
Value = category;
}
}
public class Item
{
public string Name { get; set; }
public Category Category { get; set; }
public bool IsActive { get; set; }
public DateTimeOffset CreatedAt { get; set; }
public IReadOnlyList<string> Tags { get; set; }
}
class Program
{
public void Init()
{
Category category = new Category("categoryX");
var obj1 = new Item
{
Category = category
};
var obj2 = new Item
{
Category = category
};
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1015 次 |
| 最近记录: |