forked from menault/2026_TD3_DEV51_Qualite_Algo
opti tri_par_montant
This commit is contained in:
@@ -71,15 +71,48 @@ Transaction *generer_transactions(int n)
|
|||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
/* F1 : trie les transactions par montant croissant, puis par id */
|
/* F1 : trie les transactions par montant croissant, puis par id */
|
||||||
void trier_par_montant(Transaction *t, int n)
|
static void fusionner(Transaction *t, int debut, int milieu, int fin) {
|
||||||
{
|
int n1 = milieu - debut + 1;
|
||||||
for (int i = 0; i < n - 1; i++) {
|
int n2 = fin - milieu;
|
||||||
for (int j = 0; j < n - 1 - i; j++) {
|
|
||||||
if (t[j].montant > t[j + 1].montant ||
|
Transaction *gauche = malloc(n1 * sizeof(Transaction));
|
||||||
(t[j].montant == t[j + 1].montant && t[j].id > t[j + 1].id)) {
|
Transaction *droite = malloc(n2 * sizeof(Transaction));
|
||||||
Transaction tmp = t[j];
|
|
||||||
t[j] = t[j + 1];
|
for (int i = 0; i < n1; i++)
|
||||||
t[j + 1] = tmp;
|
gauche[i] = t[debut + i];
|
||||||
|
for (int j = 0; j < n2; j++)
|
||||||
|
droite[j] = t[milieu + 1 + j];
|
||||||
|
|
||||||
|
int i = 0, j = 0, k = debut;
|
||||||
|
|
||||||
|
while (i < n1 && j < n2) {
|
||||||
|
if (gauche[i].montant < droite[j].montant ||
|
||||||
|
(gauche[i].montant == droite[j].montant && gauche[i].id <= droite[j].id)) {
|
||||||
|
t[k++] = gauche[i++];
|
||||||
|
} else {
|
||||||
|
t[k++] = droite[j++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i < n1)
|
||||||
|
t[k++] = gauche[i++];
|
||||||
|
while (j < n2)
|
||||||
|
t[k++] = droite[j++];
|
||||||
|
|
||||||
|
free(gauche);
|
||||||
|
free(droite);
|
||||||
|
}
|
||||||
|
|
||||||
|
void trier_par_montant(Transaction *t, int n) {
|
||||||
|
if (n <= 1) return;
|
||||||
|
|
||||||
|
for (int taille = 1; taille < n; taille *= 2) {
|
||||||
|
for (int debut = 0; debut < n - 1; debut += 2 * taille) {
|
||||||
|
int milieu = debut + taille - 1;
|
||||||
|
int fin = (debut + 2 * taille - 1 < n - 1) ? (debut + 2 * taille - 1) : (n - 1);
|
||||||
|
|
||||||
|
if (milieu < fin) {
|
||||||
|
fusionner(t, debut, milieu, fin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+43
-11
@@ -1,13 +1,45 @@
|
|||||||
complexités Algorithmique :
|
# Compte rendu — TD3 Complexité algorithmique (R5.A.04)
|
||||||
|
|
||||||
F1 : O(n^2)
|
## 1. Complexités algorithmiques
|
||||||
F2 : O(n^2)
|
|
||||||
F3 : O(n*c)
|
|
||||||
F4 : O(n*J)
|
|
||||||
F5 : O(J^3)
|
|
||||||
F6 : O(n)
|
|
||||||
F7: O(n^2)
|
|
||||||
F8 : O(2^S)
|
|
||||||
F9 : M=14
|
|
||||||
F10 : O(L)
|
|
||||||
|
|
||||||
|
| Fonction | Rôle | Avant | Après |
|
||||||
|
|---|---|---|---|
|
||||||
|
| F1 | `trier_par_montant` — tri par montant puis par id | O(n²) | **O(n log n)** (tri fusion) |
|
||||||
|
| F2 | `nb_clients_distincts` | O(n²) | |
|
||||||
|
| F3 | `total_par_client` | O(n·c) | |
|
||||||
|
| F4 | `total_par_jour` | O(n·J) | |
|
||||||
|
| F5 | `meilleure_periode` | O(J³) | |
|
||||||
|
| F6 | `rechercher_par_id` | O(n) | |
|
||||||
|
| F7 | `nb_paires_opposees` | O(n²) | |
|
||||||
|
| F8 | `nb_facons_rendre` | O(2^S) | |
|
||||||
|
| F9 | `categorie` | M = 14 | |
|
||||||
|
| F10 | `ajouter_ligne` | O(L) | |
|
||||||
|
|
||||||
|
## 2. Profil gprof initial
|
||||||
|
|
||||||
|
Programme d'origine compilé avec `gcc -O0 -g -pg`, temps total mesuré : **6,83 s**.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
`trier_par_montant` représente à elle seule **48 %** du temps (3,28 s) : c'est la première fonction à optimiser.
|
||||||
|
|
||||||
|
## 3. Optimisations
|
||||||
|
|
||||||
|
### 3.1 F1 — `trier_par_montant` : tri à bulles → tri fusion
|
||||||
|
|
||||||
|
**Avant :** tri à bulles, deux boucles imbriquées qui comparent et échangent les éléments voisins → O(n²).
|
||||||
|
|
||||||
|
**Après :** tri fusion itératif (ascendant). On fusionne des sous-tableaux triés de taille 1, 2, 4, 8… jusqu'à couvrir tout le tableau. La fonction `fusionner` copie les deux moitiés dans des tableaux temporaires puis les recombine dans l'ordre → O(n log n).
|
||||||
|
|
||||||
|
L'ordre de tri est conservé (montant croissant, puis id croissant en cas d'égalité), donc l'empreinte reste `ff68d260a7a58441`.
|
||||||
|
|
||||||
|
**Profil gprof après modification :**
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
| | Avant | Après |
|
||||||
|
|---|---|---|
|
||||||
|
| Temps de `trier_par_montant` | 3,28 s | 0,01 s (via `fusionner`) |
|
||||||
|
| Temps total du programme | 6,83 s | 3,06 s |
|
||||||
|
|
||||||
|
Le tri passe de 48 % du temps à un coût négligeable ; le temps total est divisé par plus de 2. Les fonctions les plus coûteuses sont maintenant `nb_facons_rendre` (30 %), `nb_paires_opposees` (24 %) et `rechercher_par_id` (22 %).
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 60 KiB |
+61
-60
@@ -2,82 +2,83 @@ Flat profile:
|
|||||||
|
|
||||||
Each sample counts as 0.01 seconds.
|
Each sample counts as 0.01 seconds.
|
||||||
% cumulative self self total
|
% cumulative self self total
|
||||||
time seconds seconds calls s/call s/call name
|
time seconds seconds calls ms/call ms/call name
|
||||||
48.02 3.28 3.28 1 3.28 3.28 trier_par_montant
|
30.39 0.93 0.93 1 930.00 930.00 nb_facons_rendre
|
||||||
12.59 4.14 0.86 30000 0.00 0.00 rechercher_par_id
|
23.86 1.66 0.73 1 730.00 730.00 nb_paires_opposees
|
||||||
11.71 4.94 0.80 1 0.80 0.80 nb_paires_opposees
|
21.57 2.32 0.66 30000 0.02 0.02 rechercher_par_id
|
||||||
9.96 5.62 0.68 1 0.68 0.68 nb_facons_rendre
|
8.50 2.58 0.26 6017 0.04 0.04 longueur
|
||||||
6.30 6.05 0.43 6017 0.00 0.00 longueur
|
7.52 2.81 0.23 1 230.00 230.00 meilleure_periode
|
||||||
4.69 6.37 0.32 1 0.32 0.32 meilleure_periode
|
3.59 2.92 0.11 1 110.00 110.00 nb_clients_distincts
|
||||||
2.20 6.52 0.15 _init
|
2.61 3.00 0.08 1 80.00 80.00 total_par_client
|
||||||
1.76 6.64 0.12 1 0.12 0.12 total_par_client
|
1.31 3.04 0.04 1 40.00 40.00 total_par_jour
|
||||||
1.46 6.74 0.10 1 0.10 0.10 nb_clients_distincts
|
0.33 3.05 0.01 30000 0.00 0.00 categorie
|
||||||
0.88 6.80 0.06 1 0.06 0.06 total_par_jour
|
0.33 3.06 0.01 29999 0.00 0.00 fusionner
|
||||||
0.44 6.83 0.03 30000 0.00 0.00 categorie
|
0.00 3.06 0.00 149998 0.00 0.00 alea
|
||||||
0.00 6.83 0.00 149998 0.00 0.00 alea
|
0.00 3.06 0.00 6017 0.00 0.04 ajouter_ligne
|
||||||
0.00 6.83 0.00 6017 0.00 0.00 ajouter_ligne
|
0.00 3.06 0.00 1 0.00 0.00 empreinte
|
||||||
0.00 6.83 0.00 1 0.00 0.00 empreinte
|
0.00 3.06 0.00 1 0.00 0.00 generer_transactions
|
||||||
0.00 6.83 0.00 1 0.00 0.00 generer_transactions
|
0.00 3.06 0.00 1 0.00 10.00 trier_par_montant
|
||||||
|
|
||||||
Call graph
|
Call graph
|
||||||
|
|
||||||
|
|
||||||
granularity: each sample hit covers 4 byte(s) for 0.15% of 6.83 seconds
|
granularity: each sample hit covers 4 byte(s) for 0.33% of 3.06 seconds
|
||||||
|
|
||||||
index % time self children called name
|
index % time self children called name
|
||||||
<spontaneous>
|
<spontaneous>
|
||||||
[1] 97.8 0.00 6.68 main [1]
|
[1] 100.0 0.00 3.06 main [1]
|
||||||
3.28 0.00 1/1 trier_par_montant [2]
|
0.93 0.00 1/1 nb_facons_rendre [2]
|
||||||
0.86 0.00 30000/30000 rechercher_par_id [3]
|
0.73 0.00 1/1 nb_paires_opposees [3]
|
||||||
0.80 0.00 1/1 nb_paires_opposees [4]
|
0.66 0.00 30000/30000 rechercher_par_id [4]
|
||||||
0.68 0.00 1/1 nb_facons_rendre [5]
|
0.00 0.26 6017/6017 ajouter_ligne [5]
|
||||||
0.00 0.43 6017/6017 ajouter_ligne [6]
|
0.23 0.00 1/1 meilleure_periode [7]
|
||||||
0.32 0.00 1/1 meilleure_periode [8]
|
0.11 0.00 1/1 nb_clients_distincts [8]
|
||||||
0.12 0.00 1/1 total_par_client [10]
|
0.08 0.00 1/1 total_par_client [9]
|
||||||
0.10 0.00 1/1 nb_clients_distincts [11]
|
0.04 0.00 1/1 total_par_jour [10]
|
||||||
0.06 0.00 1/1 total_par_jour [12]
|
0.01 0.00 30000/30000 categorie [11]
|
||||||
0.03 0.00 30000/30000 categorie [13]
|
0.00 0.01 1/1 trier_par_montant [13]
|
||||||
0.00 0.00 1/1 generer_transactions [16]
|
0.00 0.00 1/1 generer_transactions [16]
|
||||||
0.00 0.00 1/1 empreinte [15]
|
0.00 0.00 1/1 empreinte [15]
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
3.28 0.00 1/1 main [1]
|
266723738 nb_facons_rendre [2]
|
||||||
[2] 48.0 3.28 0.00 1 trier_par_montant [2]
|
0.93 0.00 1/1 main [1]
|
||||||
|
[2] 30.4 0.93 0.00 1+266723738 nb_facons_rendre [2]
|
||||||
|
266723738 nb_facons_rendre [2]
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
0.86 0.00 30000/30000 main [1]
|
0.73 0.00 1/1 main [1]
|
||||||
[3] 12.6 0.86 0.00 30000 rechercher_par_id [3]
|
[3] 23.9 0.73 0.00 1 nb_paires_opposees [3]
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
0.80 0.00 1/1 main [1]
|
0.66 0.00 30000/30000 main [1]
|
||||||
[4] 11.7 0.80 0.00 1 nb_paires_opposees [4]
|
[4] 21.6 0.66 0.00 30000 rechercher_par_id [4]
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
266723738 nb_facons_rendre [5]
|
0.00 0.26 6017/6017 main [1]
|
||||||
0.68 0.00 1/1 main [1]
|
[5] 8.5 0.00 0.26 6017 ajouter_ligne [5]
|
||||||
[5] 10.0 0.68 0.00 1+266723738 nb_facons_rendre [5]
|
0.26 0.00 6017/6017 longueur [6]
|
||||||
266723738 nb_facons_rendre [5]
|
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
0.00 0.43 6017/6017 main [1]
|
0.26 0.00 6017/6017 ajouter_ligne [5]
|
||||||
[6] 6.3 0.00 0.43 6017 ajouter_ligne [6]
|
[6] 8.5 0.26 0.00 6017 longueur [6]
|
||||||
0.43 0.00 6017/6017 longueur [7]
|
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
0.43 0.00 6017/6017 ajouter_ligne [6]
|
0.23 0.00 1/1 main [1]
|
||||||
[7] 6.3 0.43 0.00 6017 longueur [7]
|
[7] 7.5 0.23 0.00 1 meilleure_periode [7]
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
0.32 0.00 1/1 main [1]
|
0.11 0.00 1/1 main [1]
|
||||||
[8] 4.7 0.32 0.00 1 meilleure_periode [8]
|
[8] 3.6 0.11 0.00 1 nb_clients_distincts [8]
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
<spontaneous>
|
0.08 0.00 1/1 main [1]
|
||||||
[9] 2.2 0.15 0.00 _init [9]
|
[9] 2.6 0.08 0.00 1 total_par_client [9]
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
0.12 0.00 1/1 main [1]
|
0.04 0.00 1/1 main [1]
|
||||||
[10] 1.8 0.12 0.00 1 total_par_client [10]
|
[10] 1.3 0.04 0.00 1 total_par_jour [10]
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
0.10 0.00 1/1 main [1]
|
0.01 0.00 30000/30000 main [1]
|
||||||
[11] 1.5 0.10 0.00 1 nb_clients_distincts [11]
|
[11] 0.3 0.01 0.00 30000 categorie [11]
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
0.06 0.00 1/1 main [1]
|
0.01 0.00 29999/29999 trier_par_montant [13]
|
||||||
[12] 0.9 0.06 0.00 1 total_par_jour [12]
|
[12] 0.3 0.01 0.00 29999 fusionner [12]
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
0.03 0.00 30000/30000 main [1]
|
0.00 0.01 1/1 main [1]
|
||||||
[13] 0.4 0.03 0.00 30000 categorie [13]
|
[13] 0.3 0.00 0.01 1 trier_par_montant [13]
|
||||||
|
0.01 0.00 29999/29999 fusionner [12]
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
0.00 0.00 149998/149998 generer_transactions [16]
|
0.00 0.00 149998/149998 generer_transactions [16]
|
||||||
[14] 0.0 0.00 0.00 149998 alea [14]
|
[14] 0.0 0.00 0.00 149998 alea [14]
|
||||||
@@ -92,8 +93,8 @@ index % time self children called name
|
|||||||
|
|
||||||
Index by function name
|
Index by function name
|
||||||
|
|
||||||
[9] _init [16] generer_transactions [4] nb_paires_opposees
|
[5] ajouter_ligne [16] generer_transactions [3] nb_paires_opposees
|
||||||
[6] ajouter_ligne [7] longueur [3] rechercher_par_id
|
[14] alea [6] longueur [4] rechercher_par_id
|
||||||
[14] alea [8] meilleure_periode [10] total_par_client
|
[11] categorie [7] meilleure_periode [9] total_par_client
|
||||||
[13] categorie [11] nb_clients_distincts [12] total_par_jour
|
[15] empreinte [8] nb_clients_distincts [10] total_par_jour
|
||||||
[15] empreinte [5] nb_facons_rendre [2] trier_par_montant
|
[12] fusionner (banque.c) [2] nb_facons_rendre [13] trier_par_montant
|
||||||
|
|||||||
Reference in New Issue
Block a user