包含接口的两个列表与包含具有两个接口的结构的一个List

Mar*_*kus 7 c#

我有两个接口.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);
}
Run Code Online (Sandbox Code Playgroud)

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

版本1:

public class CacheFramework
{
private List<ICacheHolder> cacheHolders = new List<ICacheHolder>();
private List<IVisualizer> visualizers = new List<IVisualizer>();
...
}
Run Code Online (Sandbox Code Playgroud)

版本2:

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

添加和删​​除等操作不会经常进行.只有在游戏开始时才会有很多添加电话.

版本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;
}
Run Code Online (Sandbox Code Playgroud)

版本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;
}
Run Code Online (Sandbox Code Playgroud)

列表将至少通过其索引每帧访问.

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

编辑1:

修复了AddSimulationObject Version 2中的错误.

正如AddSimulationObject Version 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;
}
Run Code Online (Sandbox Code Playgroud)

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

编辑2:

我正在使用Unity3D,它主要支持.NET.3.5

正如所指出的那样,使用比List更快查找的.NET集合可能更好.或者如果列表是可排序的,请使用List.BinarySearch.

编辑3:

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

Tam*_*dus 1

我建议您使用 struct 方法,原因有两个:

  • 在.NET中,结构体泛型类型参数被特殊对待,不会发生装箱
  • 这种方法将通过结构确保您拥有匹配的元素。对我来说,感觉更容易推理。

因此,当谈到是否使用结构列表列表结构的问题时,我当然更喜欢使用结构列表,即使它会导致一点性能下降。就您而言,我希望结构版本列表的性能更好,但我不能保证这一点。您可以随时运行分析。但有一点是肯定的:性能差异远小于AddSimulationObject.