高效对象等式C#

高效对象等式C#,c#,C#,我正在尝试改进以下(示例)代码的性能 然后比较输入键 for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { bool result = inputKeys[i].Equals(inputKeys[j]); } } 但是性能更差。您的比较循环效率低下。我建议您尝试使用: Distinct<TSource>(this IEnumerable<TSource>

我正在尝试改进以下(示例)代码的性能

然后比较输入键

for (int i = 0; i < 5; i++)
{
    for (int j = 0; j < 5; j++)
    {
        bool result = inputKeys[i].Equals(inputKeys[j]);
    }
}

但是性能更差。

您的比较循环效率低下。我建议您尝试使用:

Distinct<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
Distinct(此IEnumerable源代码,IEqualityComparer比较器)

为该类型定义
IEqualityComparer
,并将其传递给该方法。您不会得到bool,但会得到一个包含列表的
IEnumerable
,其中没有重复项。

尝试获取每个对象的哈希代码,并将其与
对象进行比较。GetHashCode()
。不确定调用
GetHashCode()
几百万次的开销,但是比较两个int可能比
Equals(object)
方法快得多。

作为算法效率的一个例子,可以重写第一个代码

for (int i = 0; i < 5; i++)
{
    for (int j = i; j < 5; j++)
    {
        bool result = inputKeys[i].Equals(inputKeys[j]);
    }
}
for(int i=0;i<5;i++)
{
对于(int j=i;j<5;j++)
{
bool result=inputKeys[i]。等于(inputKeys[j]);
}
}
因为x.Equals(y)将给出与y.Equals相同的结果,所以不需要同时进行检查。

平等的新实施应遵循《公约》的所有保障

x、 Equals(y)返回与y.Equals(x)相同的值

使用哈希表(最好是字典)来存储项目。 您的方法的顺序为(N^2),通过使用哈希表,可以将运行时间复杂性降低到O(N),其中N是数字

要实现这一点,请使用哈希键创建哈希表,如果发生冲突,请将项添加到链接列表中。当只需要检查同一个bucket中的对象是否相等时,这不应该太多


我希望这是清楚和有帮助的。

正如评论中所说,你的算法的主要负担是你必须把所有的东西都与所有的东西进行比较,这会降低你的性能。对于100K元素,意味着100K^2。。。或者大约1亿个组合。。。你可以看到哪里有问题。最好的选择是修改算法,但是,如果您仍然确定或没有任何其他选择,请考虑:

先分割对象,然后比较:

示例:如果有100K个对象均匀分布,那么将有33K个整数、33K个字符串和33K个日期时间,然后可以相互比较,忽略它们之间的组合

10万^2=1亿

(30K^2)*3=27亿个组合+10万个组合,以对其列表中的每个元素进行排序

扩展您的群组

如果你不太在意内存,你可以将结果散列以进一步优化你的组。基本上构建一个网格这是非常具体的,取决于您的问题

这背后的想法是将不可能真正平等的事情隔离开来,这是之前想法的延伸,但如果团队越多,团队越小,你的表现就越快

这样你可以有10个小组

  • 小于5个字符的字符串
  • 5到50个字符之间的字符串
  • 长度超过50个字符的字符串
等等

如果重新计算(同样,对于均匀分布的样本)

总迭代次数=10K^2*10+100K~1亿次迭代(10组+组成这些组的价格)


实际复杂度=(n/m)^2*m+n(其中n=元素数,m=假设均匀分布的组数。

您的问题在于算法本身。您将每个项目与其他项目进行比较,这需要二次时间。如果您需要比较数百万个项目,您应该找到更好的方法。一个选项(不一定是最好的)是divi按类型对数据进行反求,然后对其进行排序;这会使比较变得简单,只需要n log n时间。您希望有多少个不同的值?如果您希望有数百万个项,但只有数万个值,那么一个简单的哈希表就可以了。不可能回答。最好的方法是减少命中等于的次数。它当它更频繁时,肯定不会变慢-我确信equals调用需要相同的时间。基本用途似乎选择得很糟糕(例如:首先检查hashcode,排序列表以减少equals调用等)。这些是50多年来“众所周知”的技术(索引、数据库)。最后,问题不是等号的时间,而是你称之为数百万次-无效的算法。@TomTom是对的。不要浪费时间重写等号。.Net等号已经可以处理不同类型的比较。你的版本只需要额外的时间就可以了。请专注于围绕等号的代码。谢谢s、 但当我运行分析器(ANTS)时下降只是在等式检查上,在循环上可以忽略不计。这就是为什么我说我只希望改进等式。我同意这不是等式运算,而是他做循环的方式。将哈希代码的使用与比二次型更好的算法结合起来,它的性能应该更好。还建议阅读:观察得好,工作得好注意,将j初始化为i+1将节省O(n)个查询。
Distinct<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
for (int i = 0; i < 5; i++)
{
    for (int j = i; j < 5; j++)
    {
        bool result = inputKeys[i].Equals(inputKeys[j]);
    }
}