我正在考虑减少像集合对象这样的表的内存消耗。
给定一个类结构
Class Cell
{
public property int Data;
public property string Format;
}
Class Table
{
public property Dictionary<Position, Cell> Cells;
}
当有大量单元格时,Cell 类的 Data 属性可能是可变的,但 Format 属性可能会重复多次,例如标题单元格的标题格式字符串可能为空,数据单元格可能全部为“0.00”。
一个想法是像下面这样
Class Cell
{
public property int Data;
public property int FormatId;
}
Class Table
{
public property Dictionary<Position, Cell> Cells;
private property Dictionary<Position, string> Formats;
public string GetCellFormat(Position);
}
这会节省字符串的内存,但 FormatId 整数值仍会重复多次。
还有比这更好的实现吗?我查看了享元模式,但不确定它是否与此匹配。
我正在考虑的一个更复杂的实现是完全从 Cell 类中删除 Format 属性,而是将 Formats 存储在将相邻单元格组合在一起的字典中
例如可能有 2 个这样的条目
<item rowFrom=1 rowTo=1 format="" /
>
<item romFrom=2 rowTo=1000 format="0.00" /
>
最佳答案
对于字符串,你也许可以看看实习;使用内置的内部程序,或者(最好)自定义内部程序 - 基本上是 Dictionary<string,string>
.这意味着每个相同的字符串都使用相同的引用 - 并且可以收集重复项。
不要对 int 做任何事情;这已经是最优的。
例如:
using System;
using System.Collections.Generic;
class StringInterner {
private readonly Dictionary<string, string> lookup
= new Dictionary<string, string>();
public string this[string value] {
get {
if(value == null) return null;
if(value == "") return string.Empty;
string result;
lock (lookup) { // remove if not needed to be thread-safe
if (!lookup.TryGetValue(value, out result)) {
lookup.Add(value, value);
result = value;
}
}
return result;
}
}
public void Clear() {
lock (lookup) { lookup.Clear(); }
}
}
static class Program {
static void Main() {
// this line is to defeat the inbuilt compiler interner
char[] test = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' };
string a = new string(test), b = new string(test);
Console.WriteLine(ReferenceEquals(a, b)); // false
StringInterner cache = new StringInterner();
string c = cache[a], d = cache[b];
Console.WriteLine(ReferenceEquals(c, d)); // true
}
}
您可以使用 WeakReference
更进一步如果需要的话。
请注意,您不需要更改设计 - 您只需更改填充对象的代码即可使用内部/缓存。
关于c# - 减少相似对象的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1727502/