Mergesort を使用して 50.000.000 文字列を注文していますが、使用するパラメーター タイプに応じて 2 つの異なる結果が得られます。
インターフェイス IComparable の使用:
- 20226ミリ秒
文字列を直接使用する:
- 10912 ミリ秒
マージソート コード:
public class Mergesort2
{
static private StringComparer comparer1 = StringComparer.Ordinal;
public static void merge(IComparable[] a, IComparable[] aux, int lo, int mid, int hi)
{
for (int k = lo; k <= hi; k++)
{
aux[k] = a[k];
}
// merge back to a[]
int i = lo, j = mid + 1;
for (int k = lo; k <= hi; k++)
{
if (i > mid)
{
a[k] = aux[j++];
}
else if (j > hi)
{
a[k] = aux[i++];
}
else if (less(aux[j], aux[i]))
{
a[k] = aux[j++];
}
else
{
a[k] = aux[i++];
}
}
}
private static void sort(IComparable[] a, IComparable[] aux, int lo, int hi)
{
if (hi <= lo)
{
return;
}
int mid = lo + (hi - lo) / 2;
sort(a, aux, lo, mid);
sort(a, aux, mid + 1, hi);
merge(a, aux, lo, mid, hi);
}
public static void sort(IComparable[] a)
{
IComparable[] aux = new IComparable[a.Length];
sort(a, aux, 0, a.Length - 1);
}
///*********************************************************************
/// Helper sorting functions
/// **********************************************************************
// is v < w ?
private static bool less(IComparable v, IComparable w)
{
return (comparer1.Compare(v, w) < 0);
}
// exchange a[i] and a[j]
private static void exch(Object[] a, int i, int j)
{
Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}
/// <summary>
///*********************************************************************
/// Index mergesort
/// **********************************************************************
/// </summary>
// stably merge a[lo .. mid] with a[mid+1 .. hi] using aux[lo .. hi]
private static void merge(IComparable[] a, int[] index, int[] aux, int lo, int mid, int hi)
{
// copy to aux[]
for (int k = lo; k <= hi; k++)
{
aux[k] = index[k];
}
// merge back to a[]
int i = lo, j = mid + 1;
for (int k = lo; k <= hi; k++)
{
if (i > mid)
{
index[k] = aux[j++];
}
else if (j > hi)
{
index[k] = aux[i++];
}
else if (less(a[aux[j]], a[aux[i]]))
{
index[k] = aux[j++];
}
else
{
index[k] = aux[i++];
}
}
}
// return a permutation that gives the elements in a[] in ascending order
// do not change the original array a[]
public static int[] indexSort(IComparable[] a)
{
int N = a.Length;
int[] index = new int[N];
for (int i = 0; i < N; i++)
{
index[i] = i;
}
int[] aux = new int[N];
sort(a, index, aux, 0, N - 1);
return index;
}
// mergesort a[lo..hi] using auxiliary array aux[lo..hi]
private static void sort(IComparable[] a, int[] index, int[] aux, int lo, int hi)
{
if (hi <= lo)
{
return;
}
int mid = lo + (hi - lo) / 2;
sort(a, index, aux, lo, mid);
sort(a, index, aux, mid + 1, hi);
merge(a, index, aux, lo, mid, hi);
}
}
このコードにより、ランタイムが遅くなります。
すべてのIComparable型をStringに変更すると、パフォーマンスが向上します。異なるタイプを使用すると、なぜこれほど大きなパフォーマンスの違いがあるのでしょうか?