opti tri_par_montant

This commit is contained in:
2026-10-21 12:04:00 +02:00
parent 11303d3e2b
commit 8cce27c295
7 changed files with 146 additions and 80 deletions
+42 -9
View File
@@ -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);
} }
} }
} }
BIN
View File
Binary file not shown.
+43 -11
View File
@@ -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**.
![Profil gprof initial](gprof/1-%20Original.png)
`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 :**
![Profil gprof après tri fusion](gprof/2_modif_tri_par_montant.png)
| | 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 %).
BIN
View File
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

+61 -60
View File
@@ -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