C#对象比较和内存分配

BjarkiHeiðar

我的同事CopyIfDifferent对大多数基本类型都具有10个功能。stringintdoublebool...

我对1000万个项目进行了测试,在我的机器上更改值比检查它们是否不同然后更改它们快40%左右。我测试了1000万个不需要更改的项目和1000万个需要更改的项目。

问他为什么具有这些功能,而不是仅仅因为便宜些而更改值。他告诉我,这是为了防止内存分配和内存碎片。因此,如果对象相同,则它可以保留在相同的内存地址中,因此速度更快。

public static void CopyIfDifferent(ref string vValueToCopyTo, string vValueToCopyFrom)
{
    if (!ValuesAreEqual(vValueToCopyTo, vValueToCopyFrom))
    {
        vValueToCopyTo = vValueToCopyFrom;
    }
}
public static bool ValuesAreEqual(string vValue1, string vValue2)
{
    if (vValue1 == null && vValue2 == null)
    {
        return true;
    }
    if (vValue1 == null || vValue2 == null)
    {
        return false;
    }
    return vValue1 == vValue2;
}

使用功能

Utils.CopyIfDifferent(ref GroupIDFK, item.GroupIDFK);

我的问题是。在更改值之前检查值而不是仅更改值会更好吗?如果可以,为什么?

马修·沃森(Matthew Watson)

仅查看字符串函数,如果有什么增加内存使用量的话,请不要减少它。(但是,由于使用字符串实习,通常不会实际增加内存使用,但也无济于事。)

为什么?好吧,让我们看一下方法:

public static void CopyIfDifferent(ref string vValueToCopyTo, string vValueToCopyFrom)
{
    if (!ValuesAreEqual(vValueToCopyTo, vValueToCopyFrom))
    {
        vValueToCopyTo = vValueToCopyFrom;
    }
}

现在考虑当字符串不同时调用它:

string s1 = "One";
string s2 = "Two";

CopyIfDifferent(ref s2, s1);

这会做什么?好吧,它将和执行以下操作完全相同:

s2 = s1;

仅带有方法调用的开销和昂贵的字符串比较。所以这毫无意义。

现在,如果字符串相同怎么办?在这种情况下,它什么也不做,将保留s2其原始引用。这意味着我们现在有两个对具有相同内容而不是一个内容的字符串的引用,这表面上浪费了内存,并使情况变得更糟。幸运的是,由于使用了字符串实习,因此通常仅将一个字符串的一个实际副本保留在内存中,这可以稍微缓解该问题。

因此,总的来说,这完全是浪费时间,会使事情变慢,您当然不应该这样做。

以及如何使用诸如这样的值类型int呢?如果实现如下所示:

public static void CopyIfDifferent(ref int vValueToCopyTo, int vValueToCopyFrom)
{
    if (!ValuesAreEqual(vValueToCopyTo, vValueToCopyFrom))
    {
        vValueToCopyTo = vValueToCopyFrom;
    }
}

public static bool ValuesAreEqual(int vValue1, int vValue2)
{
    return vValue1 == vValue2;
}

那太可怕了...

一个简单的操作int x = y;就变成了将指针推到堆栈(ref参数)上的效率低下,然后取消对指针的引用(在比较值时),然后在值不同时将其分配给指针。

就像@dcastro指出的那样,int无论如何它都会被复制3次-这完全是嘲笑试图首先优化a的复制int

就是不行。一千次,没有。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章