まず、ToList() を削除します。この操作は必要ありませんので、削除してください。それは物事を少しスピードアップします。
残りの部分: いいえ、これより速い方法はありません。最初に 2 倍のパフォーマンス向上を示すコードで回答を投稿した場合。
なんで?OrderBy 全体は、キーの生成と、それらのキーを比較することによる値のソートの 2 つの部分に分かれています。配列内のアイテムの数が増えると、キーの生成は自然に増えますが、比較操作の数は指数関数的に増えます。
私のコードでは、すべての値を 10 進数に変換する必要はありませんでしたが (キー生成中の速度が向上しました)、ソート中に値をボックス化解除する必要がありました。これはパフォーマンスの低下です。より大きな配列では、比較操作の数が指数関数的に増加したため、ボックス化解除の数が増加し、最終的には砂の中の砂でした.
2種類の数値を受け入れるデリゲートを作成し、そのデリゲートで、両方のタイプの最適な比較ソリューションを備えた動的なコンパイル済みコードを作成するなど、他のソリューションを試しました。これには、数値を変換する必要がある場合が常にあります。そして、仕分けフェイズの間、これは殺しになります。
簡単に言えば、いいえ、ルーチンをより速くすることはできません. コンペアフェイズが可能な限り高速である限り、鍵生成フェイズにかかる時間は問題ではありません。
興味のある人は、以前の回答の元のコードを参照してください(配列が大きいほど高速ではありません)。
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 !!!