J'ai quelques questions concernant différentes implémentations de tri d'insertion.InsertionSort vs InsertionSort vs BinaryInsertionSort
Application 1:
public static void insertionSort(int[] a) {
for (int i = 1; i < a.length; ++i) {
int key = a[i];
int j = i - 1;
while (j >= 0 && a[j] > key) {
a[j + 1] = a[j];
--j;
}
a[j + 1] = key;
}
}
Mise en œuvre 2:
public static void insertionSort(int[] a) {
for (int i = 1; i < a.length; ++i) {
for (int j = i; j > 0 && a[j - 1] > a[j]; --j) {
swap(a, j, j - 1);
}
}
}
private static void swap(int[] a, int i, int j) {
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
Voilà ma première question: Il faut penser que la première version devrait être un peu plus rapide que la deuxième version (en raison des affectations moins) mais ce n'est pas (ou du moins la différence c'est négligeable). Mais pourquoi? Deuxièmement, je me demandais que la méthode Arrays.sort() de Java utilise aussi la seconde approche (peut-être à cause de la réutilisation du code parce que la méthode swap est utilisée à différents endroits, peut-être parce qu'elle est plus facile à comprendre).
Mise en œuvre 3 (binaryInsertionSort):
public static void binaryInsertionSort(int[] a) {
for (int i = 1; i < a.length; ++i) {
int pos = Arrays.binarySearch(a, 0, i, a[i]);
int insertionPoint = (pos >= 0) ? pos : -pos - 1;
if (insertionPoint < i) {
int key = a[i];
// for (int j = i; i > insertionPoint; --i) {
// a[j] = a[j - 1];
// }
System.arraycopy(a, insertionPoint, a, insertionPoint + 1, i - insertionPoint);
a[insertionPoint] = key;
}
}
}
est le genre d'insertion binaire d'une utilisation pratique, ou est-il plus d'une chose théorique? Sur les petits réseaux, les autres approches sont beaucoup plus rapides, et sur les réseaux plus grands, mergesort/quicksort a de meilleures performances.
Je suppose que la différence est négligeable car: pour les petits réseaux, tout le temps pris est négligeable; pour les grands tableaux, le temps nécessaire est dominé par les performances du cache. Étant donné que les écritures supplémentaires dans la deuxième version sont adjacentes aux écritures que les deux versions effectuent, la deuxième version ne nécessite pas l'accès à des lignes de cache supplémentaires, donc les performances ne sont pas affectées. C'est juste une supposition, cependant, il est même possible que votre JIT les a optimisés pour être plus ou moins identiques, et je n'aurais pas été surpris qu'il y ait eu une différence de performance. –