Dictionary ContainsValue()导致程序停止响应

时间:2015-05-05 22:34:24

标签: c# dictionary unity3d

我使用字典来存储网格点,我不想为每个网格点显示Handle,因为3个点共享相同的Vector3位置,所以我正在存储字典中的点,然后检查字典以查看该值是否存在,如果没有添加句柄并将该点添加到字典中,否则只需将该点添加到字典中,而不是创建额外的句柄。

当我运行它时,编辑器停止响应并且我必须强制退出,导致问题的是我的if语句。如果我注释掉它是否正常。如果我只添加所有句柄并使用否,它也可以工作,但由于所有句柄它运行缓慢。

网格有大约23k个顶点。我该怎么做才能优化它?

public void OnSceneGUI(){
    Creator t = (Creator)target;
    Mesh mesh = t.GetComponent<MeshFilter>().sharedMesh;
    if (mesh != null) {
        Vector3[] vertices = mesh.vertices;

        Vector3 lp = t.transform.position;
        Handles.color = Color.red;
        Dictionary<int, Vector3> dict = new Dictionary<int, Vector3> ();
        int i = 0;
        foreach (Vector3 v in vertices) {
            Vector3 p = lp - v;
            Vector3 pos = new Vector3 (p.x, -p.z, p.y);

            if(dict.ContainsValue(pos)){
                Handles.FreeMoveHandle(pos, Quaternion.identity, 0.001f, Vector3.zero, Handles.DotCap);
            }

            dict.Add (i, pos);
            i++;

        }
    }
}

1 个答案:

答案 0 :(得分:4)

你在这里误导了Dictionary

  • ContainsValue必须枚举整个字典,以了解给定值是否在内部。这是因为词典由索引,而不是由索引。它是O(n)操作。

  • 如果您只使用Add字词,而不使用密钥,那么您只需删除字典,不要将其用于其他任何内容。您未使用映射功能,该功能已针对字典进行了优化。

尝试使用HashSet

var handles = new HashSet<Vector3>();

foreach (Vector3 v in vertices) {
    Vector3 p = lp - v;
    Vector3 pos = new Vector3 (p.x, -p.z, p.y);

    if (!handles.Add(pos)) {
        Handles.FreeMoveHandle(pos, Quaternion.identity, 0.001f, Vector3.zero, Handles.DotCap);
    }
}

HashSet&#39; Add方法返回bool,告诉您该值是否已添加(true),或者是否已存在于集合中(false)。