生成网格的最有效方法';unity/c#中的s字符串哈希?

生成网格的最有效方法';unity/c#中的s字符串哈希?,c#,performance,unity3d,hash,mesh,C#,Performance,Unity3d,Hash,Mesh,作为我当前项目的一部分,我需要为Unity中的网格生成哈希。这些用于稍后检查网格内容是否已更改。出于接口考虑,不幸的是,哈希必须是字符串的形式 我目前的做法如下: public override string GetHash() { StringBuilder hash = new StringBuilder(); hash.Append("v"); foreach (Vector3 val

作为我当前项目的一部分,我需要为Unity中的网格生成哈希。这些用于稍后检查网格内容是否已更改。出于接口考虑,不幸的是,哈希必须是字符串的形式

我目前的做法如下:

        public override string GetHash()
        {
            StringBuilder hash = new StringBuilder();
            hash.Append("v");
            foreach (Vector3 val in this.v)
            {
                hash.Append(val.ToString());
            }
            hash.Append("n");
            foreach (Vector3 val in this.n)
            {
                hash.Append(val.ToString());
            }
            hash.Append("u");
            foreach (Vector2 val in this.u)
            {
                hash.Append(val.ToString());
            }
            hash.Append("v");
            foreach (int val in this.t)
            {
                hash.Append(val.ToString());
            }
            return hash.ToString();
        }
这已经成为一个重要的瓶颈,主要是由于Vector3.ToString()调用。(对于立方体基本体,大约为4-5毫秒)

是否有更高性能的方法来散列对网格中的微小更改仍然敏感的网格?

是一个
结构,如果
向量3
具有相同的值,则其
GetHashCode
实现返回相同的散列:


此外,我不知道您的确切用例,但它可能足以有一个散列的顶点位置

我建议使用类似

var output = 0;
foreach (var vertex in mesh.vertices)
{
    output = output ^ vertex.GetHashCode();
}
return output.ToString();
是一个
struct
,如果
Vector3
具有相同的值,则其
GetHashCode
实现返回相同的散列:


此外,我不知道您的确切用例,但它可能足以有一个散列的顶点位置

我建议使用类似

var output = 0;
foreach (var vertex in mesh.vertices)
{
    output = output ^ vertex.GetHashCode();
}
return output.ToString();

您可以尝试这个
GetHash
的实现。该方法是从Microsoft的源代码中窃取的

public override string GetHash()
{
    int hashCode = 0;
    foreach (Vector3 val in this.v)
    {
        hashCode = CombineHashCodes(hashCode, val.X.GetHashCode());
        hashCode = CombineHashCodes(hashCode, val.Y.GetHashCode());
        hashCode = CombineHashCodes(hashCode, val.Z.GetHashCode());
    }
    foreach (Vector3 val in this.n)
    {
        hashCode = CombineHashCodes(hashCode, val.X.GetHashCode());
        hashCode = CombineHashCodes(hashCode, val.Y.GetHashCode());
        hashCode = CombineHashCodes(hashCode, val.Z.GetHashCode());
    }
    foreach (Vector2 val in this.u)
    {
        hashCode = CombineHashCodes(hashCode, val.X.GetHashCode());
        hashCode = CombineHashCodes(hashCode, val.Y.GetHashCode());
    }
    foreach (int val in this.t)
    {
        hashCode = CombineHashCodes(hashCode, val.GetHashCode());
    }
    return hashCode.ToString();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
static int CombineHashCodes(int h1, int h2)
{
    return ((h1 << 5) + h1) ^ h2;
}
public重写字符串GetHash()
{
int hashCode=0;
foreach(此.v中的Vector3 val)
{
hashCode=组合hashCode(hashCode,val.X.GetHashCode());
hashCode=组合hashCodes(hashCode,val.Y.GetHashCode());
hashCode=组合hashCodes(hashCode,val.Z.GetHashCode());
}
foreach(此.n中的Vector3 val)
{
hashCode=组合hashCode(hashCode,val.X.GetHashCode());
hashCode=组合hashCodes(hashCode,val.Y.GetHashCode());
hashCode=组合hashCodes(hashCode,val.Z.GetHashCode());
}
foreach(在这个.u中为vector2val)
{
hashCode=组合hashCode(hashCode,val.X.GetHashCode());
hashCode=组合hashCodes(hashCode,val.Y.GetHashCode());
}
foreach(此.t中的int val)
{
hashCode=CombineHashCodes(hashCode,val.GetHashCode());
}
返回hashCode.ToString();
}
[MethodImpl(MethodImplOptions.AggressiveInline)]
静态整数组合哈希码(整数h1,整数h2)
{

return((h1您可以尝试此
GetHash
的实现。该方法是从Microsoft的源代码中窃取的

public override string GetHash()
{
    int hashCode = 0;
    foreach (Vector3 val in this.v)
    {
        hashCode = CombineHashCodes(hashCode, val.X.GetHashCode());
        hashCode = CombineHashCodes(hashCode, val.Y.GetHashCode());
        hashCode = CombineHashCodes(hashCode, val.Z.GetHashCode());
    }
    foreach (Vector3 val in this.n)
    {
        hashCode = CombineHashCodes(hashCode, val.X.GetHashCode());
        hashCode = CombineHashCodes(hashCode, val.Y.GetHashCode());
        hashCode = CombineHashCodes(hashCode, val.Z.GetHashCode());
    }
    foreach (Vector2 val in this.u)
    {
        hashCode = CombineHashCodes(hashCode, val.X.GetHashCode());
        hashCode = CombineHashCodes(hashCode, val.Y.GetHashCode());
    }
    foreach (int val in this.t)
    {
        hashCode = CombineHashCodes(hashCode, val.GetHashCode());
    }
    return hashCode.ToString();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
static int CombineHashCodes(int h1, int h2)
{
    return ((h1 << 5) + h1) ^ h2;
}
public重写字符串GetHash()
{
int hashCode=0;
foreach(此.v中的Vector3 val)
{
hashCode=组合hashCode(hashCode,val.X.GetHashCode());
hashCode=组合hashCodes(hashCode,val.Y.GetHashCode());
hashCode=组合hashCodes(hashCode,val.Z.GetHashCode());
}
foreach(此.n中的Vector3 val)
{
hashCode=组合hashCode(hashCode,val.X.GetHashCode());
hashCode=组合hashCodes(hashCode,val.Y.GetHashCode());
hashCode=组合hashCodes(hashCode,val.Z.GetHashCode());
}
foreach(在这个.u中为vector2val)
{
hashCode=组合hashCode(hashCode,val.X.GetHashCode());
hashCode=组合hashCodes(hashCode,val.Y.GetHashCode());
}
foreach(此.t中的int val)
{
hashCode=CombineHashCodes(hashCode,val.GetHashCode());
}
返回hashCode.ToString();
}
[MethodImpl(MethodImplOptions.AggressiveInline)]
静态整数组合哈希码(整数h1,整数h2)
{

返回((h1两个不同的网格生成相同散列的可能性很小吗?我指的是1/2147483647。@Theodor:如果这些碰撞与原始网格中的相似性没有关联,那么这似乎是可以接受的低。一般来说,你需要跟踪什么样的变化?如果法线或UV发生变化,这真的相关吗?不是吗如果顶点位置发生变化就足够了?@derHugo:我相信mesh.GetHashCode链接到实例,而不是网格的内容。因此,两个具有相同结构的不同网格将导致不同的哈希,不是吗?@Tobl可能是真的。但是内容如何?你不能至少将其减少到顶点吗?这是可以接受的吗两个不同的网格生成相同散列的可能性很小?我指的是1/2147483647。@Theodor:如果这些碰撞与原始网格中的相似性没有关联,那么这似乎是可以接受的低。一般来说,你需要跟踪什么样的更改?法线或UV更改是否真的相关?如果顶点位置已更改?@derHugo:我相信mesh.GetHashCode链接到实例,而不是网格的内容。因此,具有相同结构的两个不同网格将导致不同的哈希,不是吗?@Tobl可能是正确的。但是内容如何?您不能至少将其减少到顶点吗?您也可以尝试从
int
long
,以获得更小的冲突概率。在64位系统中,它可能不会更慢。您也可以尝试从
int
切换到
long
,以获得更小的冲突概率。在64位系统中,它可能不会更慢。