【发布时间】:2012-12-18 17:47:43
【问题描述】:
我正在尝试提高以下(示例)代码的性能。
Object[] inputKeys = new Object[10];
inputKeys[0] = "4021";
inputKeys[1] = "3011";
inputKeys[2] = "1010";
inputKeys[3] = "1020";
inputKeys[4] = "1030";
然后比较输入键。
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
bool result = inputKeys[i].Equals(inputKeys[j]);
}
}
inputKeys 可以是string、int32 或DateTime 的所有类型。
.Equals 行的性能大幅下降,当它达到数百万次时。
关于如何提高这条线的性能(平等检查)有什么建议吗?
我试过这个: 使用下面类的数组而不是 Object 数组来保存键。在那里我保留了 Key 类型和键值。
public class CustomKey : IEquatable<CustomKey>{
internal int KeyType { get; private set; }
internal string ValueString { get; private set; }
internal int ValueInteger { get; private set; }
internal DateTime ValueDateTime { get; private set; }
internal CustomKey(string keyValue)
{
this.KeyType = 0;
this.ValueString = (string)keyValue;
}
internal CustomKey(int keyValue)
{
this.KeyType = 1;
this.ValueInteger = (int)keyValue;
}
internal CustomKey(DateTime keyValue)
{
this.KeyType = 2;
this.ValueDateTime = (DateTime)keyValue;
}
public bool Equals(CustomKey other)
{
if (this.KeyType != other.KeyType)
{
return false;
}
else
{
if (this.KeyType == 0)
{
return this.ValueString.Equals(other.ValueString);
}
else if (this.KeyType == 1)
{
return this.ValueInteger.Equals(other.ValueInteger);
}
else if (this.KeyType == 2)
{
return this.ValueDateTime.Equals(other.ValueDateTime);
}
else
{
return false;
}
}
}
}
但性能更差。
【问题讨论】:
-
你的问题是算法本身。您正在将每个项目与每个其他项目进行比较,这需要二次时间。如果您需要比较数百万个项目,您应该找到更好的方法。一种选择——不一定是最好的——是按类型划分数据,然后对其进行排序;这将使比较变得微不足道,并且只需要 n log n 时间。
-
您期望有多少不同的值?例如,如果您期望数百万个项目但只有数万个值,那么一个简单的哈希表可能会解决问题。
-
无法回答。最好的方法是少打equals。当它更频繁时它肯定不会变慢 - 我相信一个 equals 调用需要相同的时间。基本用途似乎选择不当(例如:首先检查哈希码,排序列表以进行较少的等于调用等)。这些是 50 多年的“知名”技术(指数、数据库)。最后,问题不在于 equals 的时间,而是您称其为数百万次 - 效率低下的算法。
-
@TomTom 是对的。不要浪费时间重写 Equals。 .Net Equals 已经处理了不同类型的比较。您的版本只是额外工作了一次。而是专注于 Equals 周围的代码。
标签: c#