Commit 29c007e6 authored by ALICHERIF_YACINE's avatar ALICHERIF_YACINE
Browse files

Exercice 2 : Benchmark

parent caf9cc7b
Pipeline #4627 failed with stage
in 7 seconds
#include "arraylist.h"
#include <math.h>
#include<stdio.h>
#include<stdlib.h>
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 <stddef.h>
/**
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<stdio.h>
#include <time.h>
#include<stdlib.h>
#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;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment