首先,删除 ToList()。此操作不是必需的,因此只需将其删除。这将加快事情一点点。
其余的:不,没有更快的方法。如果首先发布一个答案,代码显示性能提高了 2 倍。但是,当我运行比具有更大数组的代码时,它变得相对较慢,甚至比原始代码还要慢。
为什么?整个 OrderBy 分为两部分:键的生成和通过比较这些键对值进行排序。如果数组中的项目数增加,键的生成会线性增长,但比较操作的数量会呈指数增长。
我的代码不需要将所有值转换为小数(密钥生成期间的速度增加),但在排序过程中需要取消装箱的值是性能下降。随着更大的数组,比较操作的数量呈指数级增长,因此拆箱的数量增加了,最终成为了沙子。
我尝试过其他解决方案,例如创建接受两种类型的数字的委托,并在该委托中使用两种类型的最佳比较解决方案的动态编译代码,这总是涉及有时必须转换数字。在分拣过程中,这变成了杀戮。
所以简单地说:不,你的例程不能更快。key-generation-fase 多少时间无关紧要,只要 compare-fase 尽可能快。
对于感兴趣的人,我之前的答案中的原始代码(使用更大的数组不会更快):
static private dynamic[] testSet = new dynamic[] { 5L, 4D, 3F, null, 2U, 1M, null, 0UL };
static void Main(string[] args)
{
Stopwatch st1 = new Stopwatch();
st1.Start();
for(int i = 0; i < 100000; i++)
Test1();
st1.Stop();
Stopwatch st2 = new Stopwatch();
st2.Start();
for(int i = 0; i < 100000; i++)
Test2();
st2.Stop();
}
static public void Test1()
{
var result = testSet.OrderBy(x => x == null ? (decimal?)null : (decimal)x).ToArray();
}
static public void Test2()
{
var result = testSet.OrderBy(x => (object)x, new HeterogeneousNumbersComparer()).ToArray();
}
public class HeterogeneousNumbersComparer : IComparer<object>
{
public int Compare(object a, object b)
{
if (a == null)
if (b == null)
return 0;
else
return -1;
else if (b == null)
return +1;
if (a.GetType() == b.GetType())
{
switch(Type.GetTypeCode(a.GetType()))
{
case TypeCode.Byte:
return ((Byte)a).CompareTo((Byte)b);
case TypeCode.Decimal:
return ((Decimal)a).CompareTo((Decimal)b);
case TypeCode.Double:
return ((Double)a).CompareTo((Double)b);
case TypeCode.Int16:
return ((Int16)a).CompareTo((Int16)b);
case TypeCode.Int32:
return ((Int32)a).CompareTo((Int32)b);
case TypeCode.Int64:
return ((Int64)a).CompareTo((Int64)b);
case TypeCode.SByte:
return ((SByte)a).CompareTo((SByte)b);
case TypeCode.Single:
return ((Single)a).CompareTo((Single)b);
case TypeCode.UInt16:
return ((UInt16)a).CompareTo((UInt16)b);
case TypeCode.UInt32:
return ((UInt32)a).CompareTo((UInt32)b);
case TypeCode.UInt64:
return ((UInt64)a).CompareTo((UInt64)b);
}
}
return Convert.ToDecimal(a).CompareTo(Convert.ToDecimal(b));
}
}
}
数字(在我的机器上是):
Test1:550ms
Test2:263ms
所以......因子2!