c# - 减少相似对象的内存

标签 c# design-patterns performance

我正在考虑减少像集合对象这样的表的内存消耗。

给定一个类结构

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/

相关文章:

c# - 为什么 System.IO.Path.Combine 有 4 个重载?

c# - 使用 UnityAutoMoqContainer 注册通用接口(interface)

design-patterns - 数据绑定(bind)只用于 UI 吗?

performance - REP 做了什么设置?

tomcat - 什么性能更好 : Jetty or Tomcat for production needs?

java - Spring builder 在 Eclipse 中运行缓慢——我可以加快它的速度吗?

c# - 将 .net core 项目发布到 iis 时出现 HTTP 错误 500.19 0x80070005

c# - 如何为大量文档取消设置字段?

java - 门面模式和管理类

c++ - 与访客设计模式实现相关的问题