c# - 存储具有相应索引的对象的最有效方法

标签 c# list performance dictionary hashtable

我想存储点的集合,它们是 Point 类的对象. ( Point 包含 positionXpositionYelectricalPotential 等属性) 他们每个人都应该有一个索引 i ,但不需要以任何方式订购。 这就是我使用字典的原因 Dictionary<int, Point> meshpoints首先。

第一个问题:
如果我只想存储具有特定索引/键的对象,字典是存储数据的最有效方式吗,尤其是当涉及到每个元素的添加、搜索和循环等性能问题时?

第二个问题:
如果我想添加一个新点,我如何获得“下一个”免费 key ?就像我有带有散列键的字典 0 , 1 , 2 , 34 ,如何获得 5下一个项目键?

选项 1: meshpoints.Keys.Max()meshpoints.Keys.Last()在我的测试中花费大量时间。

Dictionary<int, string> meshpoints = new Dictionary<int, string>();

meshpoints.Add(meshpoints.Keys.Max() + 1, "itemA");

meshpoints.Add(meshpoints.Keys.Max() + 1, "itemB");

选项 2: 创建一个单独的变量 counter在我的性能测试中相当快,但这真的是最优雅的方式吗?我的意思是,你总是有一个带有字典的单独整数值到所有方法等......

Dictionary<int, string> meshpoints = new Dictionary<int, string>();
int counter = 0;

meshpoints.Add(counter, "itemA");
counter++;

meshpoints.Add(counter, "itemB");
counter++;

选项 3: meshpoints.Count()当我随时删除项目时,将无法正常工作。

最佳答案

你不需要字典,因为你想做的事可以用一个列表来完成。

因为您使用 Count + 1 作为新 ID,您可以将自动生成的 ID 添加到 Point 类,这是一个更好的设计:

public class Point
{ 
  static private int NextID;

  int ID { get; }
  public Point()
  {
    ID = NextID++;
  }
}

List<Point> meshPoints = new List<Point>();

var meshPointA = new Point();
var meshPointB = new Point();
var meshPointC = new Point();

meshPoints.Add(meshPointA);
meshPoints.Add(meshPointB);
meshPoints.Add(meshPointC);

var meshPoint = meshPoints.Where(p => p.ID == 2).SingleOrDefault();

有了它,您在添加、插入和删除对象时永远不会有重复的 ID 或冲突。

对于选项 1,Max 不提供速度性能。

对于选项 3,使用 Count 会导致这些问题:如果你接下来添加 4 个点,先删除两个点,然后添加一个,最后一个点的 ID 为 3,而剩下的两个点的 ID 为 3 和 4...所以选项 2更好。

如果你想要一个字典,你可以通过创建一个嵌入内部字典的类来做同样的事情,它有 NextID,并提供你想要提供的方法,如 Add、Remove、ContainsX、IDs (Items. Keys), Points (Items.Values) 等等(所有你想管理的这个专门的集合):

public class PointsDictionary : IEnumerable<Point>
{
  private readonly Dictionary<int, Point> Items = new Dictionary<int, Point>();

  private int NextID;

  public Point this[int index]
  {
    get { return Items.ContainsKey(index) ? Items[index] : null; }
    set { ... }
  }

  public Dictionary<int, Point>.KeyCollection IDs
  {
    get { return Items.Keys; }
  }

  public Dictionary<int, Point>.ValueCollection Points
  {
    get { return Items.Values; }
  }

  public int Add(Point point)
  {
    int index = NextID++;
    Items.Add(index, point);
    return index;
  }

  ...

}

所以在这里,您将拥有一个强大而简洁的设计。

关于c# - 存储具有相应索引的对象的最有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58696071/

相关文章:

Java 和集合 :When to use a linked list of arrays?

C# 使用子线程回调防止调用挂起

c# - 如何自定义 ObjectQuery 的 Execute 方法?

python - 遍历两个不同长度的列表

python - 如果不在 '<a href' 中,则从列表中删除项目?

c# - 性能计数器平均计时器如何与其基数相关联?

performance - ffmpeg 在没有 avformat_find_stream_info 的情况下解码慢速调用

c# - 如何在 Azure Blob 流中启用搜索

c# - WPF 将过滤后的 ObservableCollection ICollectionView 绑定(bind)到 Combobox

python - 如何将项目列表转换为python中的变量?