EDIT3:
使用する
StringComparer comparer1 = StringComparer.Ordinal;
それ以外の
IComparable v
IComparable w
comparer1.Compare(v, w)
ランタイムの問題を解決しました。
Java と C# で並べ替えアルゴリズム (Quicksort、Mergesort など) のベンチマークをいくつか行いました。
アルゴリズムの実装と実行には、Java 7 と .NET Framework 4.5 を使用しました。Java を使用すると、すべてのアルゴリズムがより優れたランタイムを実現できることが示されました。
Quicksort のランタイムの例:
C#
- n=1000000 4433 ミリ秒
- n=2000000 10047 ミリ秒
ジャワ
- n=1000000 1311ミリ秒
- n=2000000 3164 ミリ秒
次に、プロファイリング ツールを使用して測定を行いました。C# はランタイムの 75% を文字列比較 (CompareTo) に使用しましたが、Java はランタイムの 2% しか比較に使用しませんでした。
JavaではなくC#で文字列比較が非常に高価なのはなぜですか?
編集: C# の並べ替え関数 Arrays.sort(INPUT) もテストしましたが、n=1000000 で約 3000 ミリ秒を達成できるため、コードに問題はないと思います。とにかく:
クイックソートのコードは次のとおりです。
public class Quicksort {
public static void sort(IComparable[] a) {
sort(a, 0, a.Length - 1);
}
private static void sort(IComparable[] a, int lo, int hi) {
if (hi <= lo) return;
int j = partition(a, lo, hi);
sort(a, lo, j-1);
sort(a, j+1, hi);
}
private static int partition(IComparable[] a, int lo, int hi) {
int i = lo;
int j = hi + 1;
IComparable v = a[lo];
while (true) {
while (less(a[++i], v))
if (i == hi) break;
while (less(v, a[--j]))
if (j == lo) break;
if (i >= j) break;
exch(a, i, j);
}
exch(a, lo, j);
return j;
}
public static IComparable select(IComparable[] a, int k) {
if (k < 0 || k >= a.Length) {
throw new Exception("Selected element out of bounds");
}
Rnd.Shuffle(a);
int lo = 0, hi = a.Length - 1;
while (hi > lo) {
int i = partition(a, lo, hi);
if (i > k) hi = i - 1;
else if (i < k) lo = i + 1;
else return a[i];
}
return a[lo];
}
private static bool less(IComparable v, IComparable w) {
return (v.CompareTo(w) < 0);
}
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}
}
クイックソートは次のように測定されます。
Stopwatch.Restart();
Quicksort.sort(stringArray);
Stopwatch.Stop();
EDIT2: 誰かが Java のバージョンを見たいと思っていました。IComparable の代わりに Comparable を使用し、Array.Length の代わりに Array.length を使用するのとまったく同じです。