c# - 两个包含接口(interface)的列表与一个包含具有两个接口(interface)的结构的列表

标签 c#

我有两个接口(interface)。 ICacheHolder 将由实现游戏对象逻辑的类和 IVisualizer 实现,后者将成为视觉表示。

public interface ICacheHolder
{
    void updateCacheWithCurrentState(int chachFrame);

    void resizeCache(int newSize);

    T getCacheFrame<T>(int cacheIndex, float interpolationToNext) where T : struct;
}

public interface IVisualizer
{
    void updateVisualization(ICacheHolder cacheHolder, int cacheIndex, float interpolation);
}

每个 ICacheHolder 连接到一个 IVisualizer 对象,关系是 1 对 1。 我正在尝试确定将它们存储在两个单独的列表中或作为结构存储在一个列表中是否更好(性能/内存方面)。会有很大的不同吗?如果我使用 struct 版本,会发生装箱吗?我认为列表的大小将从 100 到 1000。

版本 1:

public class CacheFramework
{
private List<ICacheHolder> cacheHolders = new List<ICacheHolder>();
private List<IVisualizer> visualizers = new List<IVisualizer>();
...
}

版本 2:

struct SimulationObject
{
    public ICacheHolder CacheHolder;
    public IVisualizer Visualizer;
}
public class CacheFramework
{
private List<SimulationObject> cacheHolder = new List<SimulationObject>();
...
}

添加和删除之类的操作不会经常执行。只有在游戏开始时才会有很多 add 调用。

版本 1:

private bool AddSimulationObject(ICacheHolder cacheHolder, IVisualizer visualizer)
{
    if (!cacheHolders.Contains(cacheHolder) && !visualizers.Contains(visualizer))
    {
        cacheHolders.Add(cacheHolder);
        visualizers.Add(visualizer);
        return true;
    }
    return false;
}

版本 2:

private bool AddSimulationObject(ICacheHolder cacheHolder, IVisualizer visualizer)
{
    int index = simulationObjects.FindIndex(
        delegate (SimulationObject simulationObject)
        {
            return simulationObject.CacheHolder == cacheHolder || simulationObject.Visualizer == visualizer;
        }
        );

    if (index >= 0 )
    {
        SimulationObject newObject;
        newObject.CacheHolder = cacheHolder;
        newObject.Visualizer = visualizer;
        return true;
    }
    return false;
}

列表至少会被访问 通过其索引的每一帧。

附加信息: 每个使用 ICacheHolder 的类都将包含一个 List<struct>具有位置、旋转或健康等数据。每个列表元素都将是时间快照。目标是来回穿越时间。

编辑 1:

修复了 AddSimulationObject 版本 2 中的错误。

正如所指出的,AddSimulationObject 版本 2 可能是:

private bool AddSimulationObject(ICacheHolder cacheHolder, IVisualizer visualizer)
{
    SimulationObject newObject = new SimulationObject { CacheHolder = cacheHolder, Visualizer = visualizer };
    if (simulationObjects.Contains(newObject))
    {
        simulationObjects.Add(newObject);
        return true;
    }
    return false;
}

但在这种情况下,我需要确保 cacheHolder 和 visualizer 不会出现在任何其他组合中。

编辑2:

我正在使用主要支持 NET 的 Unity3D。 3.5

如前所述,使用 .NET 集合可能比 List 的查找速度更快。或者,如果列表是可排序的,请使用 List.BinarySearch。

编辑 3:

我将使用结构版本。我不确定会有多少次查找。如果它会成为一个问题,我可能会更改为另一个 .NET 集合。

最佳答案

Eric Lippert 的评论非常正确。 在这种情况下,甚至没有必要尝试比较性能差异,因为集合非常小,因此无需担心 CPU 时间。

内存明智...列表结构使用连续的内存块,只有当它们非常大时才会成为内存问题。 (我的意思是数百万。)

只有其他建议: 如果您要在每个游戏周期中在这些列表中执行搜索,您可以简单地选择另一个针对查找进行了优化的结构。字典在检索项目时更有效,因为查找从索引中查找,而列表将执行项目的遍历。

关于c# - 两个包含接口(interface)的列表与一个包含具有两个接口(interface)的结构的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34268807/

相关文章:

c# - 我在 C# 中选择 k 元素子集来处理大量数据的算法

c# - C# 中的 typeof() 运算符是在堆上分配一个新的 Type 对象,还是返回一个现有的对象?

C#读取XFA表单数据

.NET 2.0 中的 C# List<T>.ConvertAll

c# - 构造函数注入(inject)和默认重载

c# - 如何在 C# 中传递通用数组?

c# - 当属性具有 IDictionary<string, string> 时反序列化对象

c# - 在 C# 中序列化这些值以在 C++ 中作为已知结构正确读取时遇到问题

C# ListView SelectAll 选择颜色

c# - 处理困惑的界面层次结构 (MSHTML) 的最佳方法是什么?