Commit 29c007e6 by ALICHERIF_YACINE

### Exercice 2 : Benchmark

parent caf9cc7b
Pipeline #4627 failed with stage
in 7 seconds
 #include "arraylist.h" #include #include #include arraylist_t * arraylist_create(int taille){ arraylist_t * res = (arraylist_t *) malloc( sizeof(arraylist_t) ); if(!res) return NULL; res->data = (int *) malloc( sizeof(int) * taille ); res->capacity = taille; res->size = 0; return res; } void arraylist_destroy(arraylist_t * a){ if( a != NULL ){ if( a->data != NULL ) free( a->data ); free( a ); } } int arraylist_pere(int clef) { return (int) floor(clef/2); } int arraylist_diminuerClef(arraylist_t * a, int clef, int val) { a->data[clef] = val; int countSwap = 0; while (clef > 0 && a->data[arraylist_pere(clef)] > a->data[clef]) { int tmp = a->data[arraylist_pere(clef)]; a->data[arraylist_pere(clef)] = a->data[clef]; a->data[clef] = tmp; countSwap++; clef = arraylist_pere(clef); } return countSwap; } int arraylist_append(arraylist_t * a, int x){ int countSwap = 0; if( a!=NULL ){ if (a->size == a->capacity) { fprintf(stderr, "Erreur : tas binaire plein."); } countSwap = arraylist_diminuerClef(a, a->size,x); a->size++; } return countSwap; } int entasser(arraylist_t * a) { /*On se trouve à la racine*/ int clef = 0; int countSwap = 0; int g = 2*clef+1; int d = 2*clef+2; int tmp = 0; while((clef < (arraylist_size(a)-1)) && (g < arraylist_size(a) && d < arraylist_size(a)) && (a->data[clef] > a->data[g] || a->data[clef] > a->data[d])) { if (a->data[g] > a->data[d]) { tmp = a->data[clef]; a->data[clef] = a->data[d]; a->data[d] = tmp; clef = d; } else { tmp = a->data[clef]; a->data[clef] = a->data[g]; a->data[g] = tmp; clef = g; } countSwap++; g = 2*clef+1; d = 2*clef+2; } return countSwap; } int arraylist_pop_back(arraylist_t * a){ int countSwap = 0; if( a!=NULL && a->size>0 ){ a->data[0] = a->data[arraylist_size(a)-1]; a->size--; countSwap = entasser(a); } return countSwap; } int arraylist_get(arraylist_t * a, int pos){ if( a != NULL && pos >0 && pos < a->size ){ return a->data[pos]; } printf("Wrong parameter pos=%d or NULL list", pos); return -1; } size_t arraylist_size(arraylist_t * a){ return ( a!=NULL) ? a->size : -1; } size_t arraylist_capacity(arraylist_t * a){ return ( a!=NULL) ? a->capacity : -1; } /* char arraylist_do_we_need_to_enlarge_capacity(arraylist_t * a){ return a->size == a->capacity ? TRUE: FALSE; } void arraylist_enlarge_capacity(arraylist_t * a){ a->capacity *= 2; a->data = (int *) realloc(a->data, sizeof(int) * a->capacity); } char arraylist_do_we_need_to_reduce_capacity(arraylist_t * a){ return ( a->size <= a->capacity/4 && a->size >4 )? TRUE: FALSE; } void arraylist_reduce_capacity(arraylist_t * a){ a->capacity /= 2; a->data = (int *) realloc(a->data, sizeof(int) * a->capacity); }*/
 #ifndef __ARRAYLIST_H #define __ARRAYLIST_H #define FALSE 0 #define TRUE 1 #include /** Tableau dynamique d'entiers. */ typedef struct arraylist_s{ // Pointeur vers la zone de mémoire où les entiers seront stockées. int * data; // Taille réelle, ou capacité de stockage, du tableau. size_t capacity; // Nombre d'éléments stockés dans le tableau. size_t size; } arraylist_t; /** Fonction d'initialisation d'un tableau dynamique. Complexité en temps/espace, pire et meilleur cas : O(1) @return Un pointeur sur un tableau dynamique nouvellement alloué. */ arraylist_t * arraylist_create(int taille); /** Fonction de libération de la mémoire occupée par un tableau dynamique. Complexité en temps/espace, pire et meilleur cas : O(1) @param a est un pointeur vers l'espace mémoire que la fonction va libérer. */ void arraylist_destroy(arraylist_t * a); /** Retourne la position du père pour le noeud de position clef. */ int arraylist_pere(int clef); /** Attribue la valeur val au noeud de position clef et trie le tas. */ int arraylist_diminuerClef(arraylist_t *a, int clef, int val); /** Ajoute une valeur dans le tableau. Complexité en temps/espace, pire cas : O(size) Complexité en temps/espace, meilleur cas : O(1) Complexité amortie : O(1) @param a est le tableau auquel on souhaite ajouter une valeur. @param x est la valeur que l'on souhaite ajouter. @returns VRAI si le tableau a été agrandit, FAUX sinon */ int arraylist_append(arraylist_t * a, int x); /** Entasse le tas depuis la racine. */ int entasser(arraylist_t * a); /** Supprime la dernière valeur du tableau. Complexité en temps, pire cas : O(size) Complexité en temps, meilleur cas : O(1) Complexité amortie : O(1) @param a est le tableau auquel on souhaite ajouter une valeur. @returns VRAI si le tableau a été réduit, FAUX sinon */ int arraylist_pop_back(arraylist_t * a); /** Renvoie la valeur située à la position donnée par l'utilisateur. Complexité en temps/espace, pire cas : O(1) @param a est un pointeur vers un tableau. @param pos est la l'indice de la case on l'utilisateur veut connaître la valeur. @returns la valeur située à la position donnée par l'utilisateur. */ int arraylist_get(arraylist_t * a, int pos); /** Renvoie le nombre d'éléments stockés dans le tableau. Complexité en temps/espace, pire cas : O(1) @param a est un pointeur vers un tableau. @returns le nombre d'éléments stockés dans le tableau. */ size_t arraylist_size(arraylist_t * a); /** Renvoie la capacité de stockage du tableau. Complexité en temps/espace, pire cas : O(1) @param a est un pointeur vers un tableau. @returns la capacité de stockage du tableau. */ size_t arraylist_capacity(arraylist_t * a); /** Cette fonction détermine la règle selon laquelle un espace mémoire plus grand sera alloué ou non. @param a est un pointeur vers un tableau. @returns VRAI si le tableau doit être agrandi, FAUX sinon. */ /*char arraylist_do_we_need_to_enlarge_capacity(arraylist_t * a);*/ /** Cette fonction augmente la capacité du tableau. @param a est un pointeur vers un tableau. */ /*void arraylist_enlarge_capacity(arraylist_t * a);*/ /** Cette fonction détermine la règle selon laquelle un espace mémoire plus petit sera alloué ou non. @param a est un pointeur vers un tableau. @returns VRAI si le tableau doit être réduit, FAUX sinon. */ /*char arraylist_do_we_need_to_reduce_capacity(arraylist_t * a);*/ /** Cette fonction réduit la capacité du tableau. @param a est un pointeur vers un tableau. */ /*void arraylist_reduce_capacity(arraylist_t * a);*/ #endif
 #include #include #include #include "arraylist.h" #include "analyzer.h" int main(int argc, char ** argv){ int i; // Tableau dynamique. arraylist_t * a = arraylist_create(1000000); // Analyse du temps pris par les opérations. analyzer_t * time_analysis = analyzer_create(); // Analyse du nombre de copies faites par les opérations. analyzer_t * copy_analysis = analyzer_create(); // Analyse du nombre d'echange pour chaque insertion. analyzer_t * swap_analysis = analyzer_create(); // Analyse de l'espace mémoire inutilisé. analyzer_t * memory_analysis = analyzer_create(); // Mesure de la durée d'une opération. struct timespec before, after; clockid_t clk_id = CLOCK_REALTIME; // utilisé comme booléen pour savoir si une allocation a été effectuée. //char memory_allocation; srand(time(NULL)); // Probabilité d'insertion p = 0.7. float prob = 0.7; // variable aleatoire. float val; // On récupère le nombre d'échange effectués pour une opération. int countSwap; // Le nombre à inserer dans le tas. int insertIntoTas; for(i = 0; i < 1000000 ; i++){ val = (float)rand()/ (float)RAND_MAX; insertIntoTas = rand()%1000000; if (val <= prob) { // Ajout d'un élément et mesure du temps pris par l'opération. clock_gettime(clk_id, &before); countSwap = arraylist_append(a, insertIntoTas); clock_gettime(clk_id, &after); // Enregistrement du temps pris par l'opération analyzer_append(time_analysis, after.tv_nsec - before.tv_nsec); // Enregistrement du nombre de copies efféctuées par l'opération. // S'il y a eu réallocation de mémoire, il a fallu recopier tout le tableau. //analyzer_append(copy_analysis, (memory_allocation)? i:1 ); // Enregistrement de l'espace mémoire non-utilisé. analyzer_append(memory_analysis,arraylist_capacity(a)-arraylist_size(a)); // Enregistrement du nombre d'echange effectué. analyzer_append(swap_analysis, countSwap); } else { // Ajout d'un élément et mesure du temps pris par l'opération. clock_gettime(clk_id, &before); countSwap = arraylist_pop_back(a); clock_gettime(clk_id, &after); // Enregistrement du temps pris par l'opération analyzer_append(time_analysis, after.tv_nsec - before.tv_nsec); // Enregistrement du nombre de copies efféctuées par l'opération. // S'il y a eu réallocation de mémoire, il a fallu recopier tout le tableau. //analyzer_append(copy_analysis, (memory_allocation)? i:1 ); // Enregistrement de l'espace mémoire non-utilisé. analyzer_append(memory_analysis,arraylist_capacity(a)-arraylist_size(a)); // Enregistrement du nombre d'echange effectué. analyzer_append(swap_analysis, countSwap); } } // Affichage de quelques statistiques sur l'expérience. fprintf(stderr, "Total cost: %Lf\n", get_total_cost(time_analysis)); fprintf(stderr, "Average cost: %Lf\n", get_average_cost(time_analysis)); fprintf(stderr, "Variance: %Lf\n", get_variance(time_analysis)); fprintf(stderr, "Standard deviation: %Lf\n", get_standard_deviation(time_analysis)); // Sauvegarde les données de l'expérience. save_values(time_analysis, "../plots/dynamic_array_time_c.plot"); save_values(copy_analysis, "../plots/dynamic_array_copy_c.plot"); save_values(memory_analysis, "../plots/dynamic_array_memory_c.plot"); save_values(swap_analysis, "../plots/dynamic_array_swap_c.plot"); // Nettoyage de la mémoire avant la sortie du programme arraylist_destroy(a); analyzer_destroy(time_analysis); analyzer_destroy(copy_analysis); analyzer_destroy(memory_analysis); analyzer_destroy(swap_analysis); return EXIT_SUCCESS; }