Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Showing
with 545 additions and 19 deletions
package p4a;
import java.util.Random;
public class MainLinkedListPersoGet {
public static void main(String[] args) {
Random rnd = new Random();
LinkedListPerso<Integer> linkedList = new LinkedListPerso<Integer>();
int nbOperation = Integer.parseInt(args[0]);
for (int i = 0; i < nbOperation; i++) {
linkedList.ajout(0, i);
}
for (int i = 0; i < nbOperation; i++) {
linkedList.acces(rnd.nextInt(nbOperation));
}
}
}
package p4a;
public class MainLinkedListPersoRemoveDecrementation {
public static void main(String[] args) {
LinkedListPerso<Integer> linkedList = new LinkedListPerso<Integer>();
int nbOperation = Integer.parseInt(args[0]);
for (int i = 0; i < nbOperation; i++) {
linkedList.ajout(0, i);
}
for (int i = nbOperation-1; i >= 0; i--) {
linkedList.suppression(i);
}
}
}
package p4a;
public class MainLinkedListPersoRemoveFirstValue {
public static void main(String[] args) {
LinkedListPerso<Integer> linkedList = new LinkedListPerso<Integer>();
int nbOperation = Integer.parseInt(args[0]);
for (int i = 0; i < nbOperation; i++) {
linkedList.ajout(0, i);
}
for (int i = 0; i < nbOperation; i++) {
linkedList.suppression(0);
}
}
}
package p4a;
public class MainLinkedListStdAddDebut {
public static void main(String[] args) {
LinkedListStd<Integer> linkedList = new LinkedListStd<Integer>();
int nbOperation = Integer.parseInt(args[0]);
for (int i = 0; i < nbOperation; i++) {
linkedList.ajout(0, 0);
}
}
}
package p4a;
public class MainLinkedListStdAddFin {
public static void main(String[] args) {
LinkedListStd<Integer> linkedList = new LinkedListStd<Integer>();
int nbOperation = Integer.parseInt(args[0]);
for (int i = 0; i < nbOperation; i++) {
linkedList.ajout(0, i);
}
}
}
package p4a;
import java.util.Random;
public class MainLinkedListStdGet {
public static void main(String[] args) {
Random rnd = new Random();
LinkedListStd<Integer> linkedList = new LinkedListStd<Integer>();
int nbOperation = Integer.parseInt(args[0]);
for (int i = 0; i < nbOperation; i++) {
linkedList.ajout(0, i);
}
for (int i = 0; i < nbOperation; i++) {
linkedList.acces(rnd.nextInt(nbOperation));
}
}
}
package p4a;
public class MainLinkedListStdGetCentre {
public static void main(String[] args) {
LinkedListStd<Integer> linkedList = new LinkedListStd<Integer>();
int nbOperation = Integer.parseInt(args[0]);
for (int i = 0; i < nbOperation; i++) {
linkedList.ajout(0, i);
}
for (int i = 0; i < nbOperation; i++) {
linkedList.acces((nbOperation/2)%2==0?nbOperation/2:(int)(nbOperation/2-0.5));
}
}
}
package p4a;
public class MainLinkedListStdRemoveDecrementation {
public static void main(String[] args) {
LinkedListStd<Integer> linkedList = new LinkedListStd<Integer>();
int nbOperation = Integer.parseInt(args[0]);
for (int i = 0; i < nbOperation; i++) {
linkedList.ajout(0, i);
}
for (int i = nbOperation-1; i >= 0; i--) {
linkedList.suppression(i);
}
}
}
package p4a;
public class MainLinkedListStdRemoveFirstValue {
public static void main(String[] args) {
LinkedListStd<Integer> linkedList = new LinkedListStd<Integer>();
int nbOperation = Integer.parseInt(args[0]);
for (int i = 0; i < nbOperation; i++) {
linkedList.ajout(0, i);
}
for (int i = 0; i < nbOperation; i++) {
linkedList.suppression(0);
}
}
}
package p4a;
public class MainTableauPersoAdd {
public static void main(String[] args) {
int nbOperation = Integer.parseInt(args[0]);
TableauPerso tab = new TableauPerso(nbOperation);
for (int i = 0; i < nbOperation; i++) {
tab.ajout(0, i);
}
}
}
package p4a;
import java.util.Random;
public class MainTableauPersoGet {
public static void main(String[] args) {
Random rnd = new Random();
int nbOperation = Integer.parseInt(args[0]);
TableauPerso tab = new TableauPerso(nbOperation);
for (int i = 0; i < nbOperation; i++) {
tab.ajout(0, i);
}
for (int i = 0; i < nbOperation; i++) {
tab.acces(rnd.nextInt(nbOperation));
}
}
}
package p4a;
public class MainTableauStdAdd {
public static void main(String[] args) {
int nbOperation = Integer.parseInt(args[0]);
TableauStd tab = new TableauStd(nbOperation);
for (int i = 0; i < nbOperation; i++) {
tab.ajout(0, i);
}
}
}
package p4a;
import java.util.Random;
public class MainTableauStdGet {
public static void main(String[] args) {
Random rnd = new Random();
int nbOperation = Integer.parseInt(args[0]);
TableauStd tab = new TableauStd(nbOperation);
for (int i = 0; i < nbOperation; i++) {
tab.ajout(0, i);
}
for (int i = 0; i < nbOperation; i++) {
tab.acces(rnd.nextInt(nbOperation));
}
}
}
package p4a;
public interface Structure {
public void ajout(Object element, int position);
public void suppression(int position);
public Object acces(int position);
}
package p4a;
public class TableauPerso implements Structure{
private Object[] tableau;
private int nbElements;
public TableauPerso(int taille) {
if (taille < 0) {
throw new IllegalArgumentException("TableauPerso : taille negative " + taille);
}
this.tableau = new Object[taille];
nbElements = 0;
}
@Override
public void ajout(Object element, int position) {
if (position < 0 || position > nbElements) {
throw new IndexOutOfBoundsException("ajout : mauvais index " + position);
}
if (nbElements >= tableau.length) {
throw new IllegalStateException("ajout : tableau plein");
}
for (int i = nbElements; i > position; i--) {
tableau[i] = tableau[i - 1];
}
tableau[position] = element;
nbElements++;
}
@Override
public void suppression(int position) {
if (position < 0 || position >= nbElements) {
throw new IndexOutOfBoundsException("suppression : position incorrecte " + position);
}
for (int i = position + 1; i < nbElements; i++) {
tableau[i - 1] = tableau[i];
}
nbElements--;
}
@Override
public Object acces(int position) {
if (position > tableau.length || position < 0) {
throw new IllegalArgumentException("acces : position incorecte");
}
return tableau[position];
}
}
package p4a;
public class TableauStd implements Structure {
private Object[] tableau;
public TableauStd(int taille) {
if (taille < 0) {
throw new IllegalArgumentException("TableauStd : taille negative " + taille);
}
this.tableau = new Object[taille];
}
@Override
public void ajout(Object element, int position) {
if (position > tableau.length) {
throw new UnsupportedOperationException("ajout : operation non supportee (taille depassee)");
}
else tableau[position] = element;
}
@Override
public void suppression(int position) {
throw new UnsupportedOperationException("suppression : operation non supportee");
}
@Override
public Object acces(int position) {
if (position > tableau.length || position < 0) {
throw new IllegalArgumentException("acces : position incorecte");
}
return tableau[position];
}
}
......@@ -4,58 +4,157 @@
## Problème
Description du Problème.
Description du Problème :
Description de tous les paramètres exploratoires du problème
Nous allons comparer les différences de performances sur 3 opérations communes à différentes structures de données (tableaux, LinkedList et ArrayList).
Nous allons également réimplementer ces opérations nous même et à nouveau comparer les différences de performance avec les implémentations standard (proposées par java).
Nous avons choisi d'utiliser le language objet java.
Opérations :
- Ajout d'un élement à une certaine position (n'exite pas pour les tableaux standards, add() pour les LinkedList / ArrayList)
- Suppression d'un élement à une certaine position(n'existe pas pour les tableaux standards, remove() pour les LinkedList / ArrayList)
- Accès d'un élement à une certaine position(tab[position] pour les tableaux, get() pour les LinkedList / ArrayList)
## Dispositif expérimental
### Organisation objet
Description de l'organisation des classes et interfaces, ou diagramme de classes.
Voila notre diagramme de classe explicitant l'organisation objet de l'application.
![](UML/diagramme.svg)
Toutes les structures de données vont implémenter une Interface *"Struture"* que nous allons créer et qui contiendra les opérations choisies.
Dans le package **Standard**, nous appelerons juste les bonnes méthodes déja présentes dans les libraires standards et dans
le package **Perso** nous réimplementerons par nous même ces opérations.
### Application
[code source de l'application](chemin)
```
Description de l'application et des arguments
```
L'application est divisée en 2 parties : les scripts shells qui appellent nos differentes classes de Main compilées en java.
Il existe un script shell pour chaque graphique et celui-ci appelle les classes Main choisies avec la commande "/usr/bin/time -f "%U,%M"
[code source des scripts shell](https://git.unistra.fr/jdubocage/P4a/-/tree/master/Scripts_Shell)
[code source des fichiers Java](https://git.unistra.fr/jdubocage/P4a/-/tree/master/P4A/src/p4a)
### Environnement de test
Description de la plateforme de test
Tout les tests ont été réalisés sur le serveur troglo.iutrs.unistra.fr
Description de la plateforme de test (extrait de /proc/cpuinfo)
```
Extrait pertinent de /proc/cpuinfo
processor : 1
vendor_id : GenuineIntel
cpu family : 15
model : 6
model name : Common KVM processor
cpu MHz : 2095.078
cache size : 16384 KB
siblings : 2
cpu cores : 2
clflush size : 64
cache_alignment : 128
address sizes : 40 bits physical, 48 bits virtual
```
### Description de la démarche systématique
Description de la démarche systématique et de l'espace d'exploration pour chaque paramètres.
Voici la démarche que nous avons suivi pour génerer des données puis produire des graphiques :
```
Suite des commandes, ou script, à exécuter pour produire les données.
1. Compiler les fichiers source dans le dossier P4A\src\p4a avec la commande javac ./*.java
2. Choisir le script shell de son choix et le copier dans le dossier P4A\src
3. Executer ce script shell pour génerer puis enregistrer les données avec la commande ./nomScript.sh > perf.csv
4. Executer la commande R pour pouvoir générer les graphiques avec ces données
5. Charger la librairie ggplot2 (commande : library(ggplot2)) puis charger les données : perf <- read.csv("perf.csv")
6. Génerer le graphique avec la commande ggplot(perf, arguments) puis exportation avec ggsave("nomGraphique.png")
```
Chaque script shell réalise le test sur les différentes structures de données 3 fois (parametrable en changeant la valeur de la variable TESTS).
Le nombre de fois que l'opération testée est executée est également parametrable via la variable NBOPERATIONS.
Cette variable est une séquence de plusieurs nombre permettant d'obtenir plusieurs points sur les graphiques.
## Résultats préalables
### Temps d'exécution
### Consommation CPU
### Ajout de Valeur
| | Tete de liste | Queue de liste |
| ----------------------------------| -------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| | ![plot](./graphiques/CPU_Linked_Array_List_Ajout_Debut_Liste.png) | ![plot](./graphiques/CPU_LinkedList_ArrayList_Ajout_Fin.png) |
### Suppression de Valeur
| | Tete de liste | Queue de liste |
| ----------------------------------| -------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| | ![plot](./graphiques/CPU_LinkedList_ArrayList_Remove_Debut.png) | ![plot](./graphiques/CPU_LinkedList_ArrayList_Remove_Fin.png) |
### Assignation de valeur (tableau)
![plot](prealable.png)
<img src="./graphiques/CPU_Tab_Assign.png" width="500"/>
### Accès de Valeur aleatoire
<img src="./graphiques/CPU_LinkedList_ArrayList_Tab_Get_Random.png" width="500"/>
### Consommation mémoire
![plot](prealable-mem.png)
### Ajout de Valeur
| | Tete de liste | Queue de liste |
| ----------------------------------| -------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| | ![plot](./graphiques/Mem_Linked_Array_List_Ajout_Debut_Liste.png) | ![plot](./graphiques/Mem_LinkedList_ArrayList_Ajout_Fin.png) |
### Suppression de Valeur
| | Tete de liste | Queue de liste |
| ----------------------------------| -------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| | ![plot](./graphiques/Mem_LinkedList_ArrayList_Remove_Debut.png) | ![plot](./graphiques/Mem_LinkedList_ArrayList_Remove_Fin.png) |
### Assignation de valeur (tableau)
<img src="./graphiques/Mem_Tab_Assign.png" width="500"/>
### Accès de Valeur aleatoire
<img src="./graphiques/Mem_LinkedList_ArrayList_Tab_Get_Random.png" width="500"/>
### Analyse des résultats préalables
La mémoire se comporte exactement pareil sur les 4 versions.
Les temps d'exécutions dépendent essentiellement de l'affichage des valeurs du tableau.
La version 2 de recherche semble un peu plus rapide.
On peut déja faire plusieurs remarques en observant les graphiques :
Pour l'ajout / suppression de valeurs (non supporté par les tableaux standards en java) :
- Les LinkedList sont bien plus efficaces en consommation CPU que les ArrayList en debut de liste.
- La différence en consommation CPU entre les deux structures est minime pour ces opérations en queue de liste.
- Les ArrayList sont légèrement moins couteuses en mémoire que les LinkedLists que soit en tete ou queue de liste.
L'assignation de valeur pour un tableau est très efficace en consommation CPU et proche des ArrayList en consommation Mémoire.
Pour l'accès de valeur aléatoire :
- Les ArrayLists et Tableaux sont très efficaces et identiques en consommation CPU.
- Les LinkedList sont beaucoup moins efficace que les deux autres structures en consommation CPU.
- En consommation mémoire, les Tableaux et ArrayLists sont proches et les LinkedList sont légerement plus couteuses.
### Discussion des résultats préalables
Explications précises et succinctes sur ce que les limites des résultats
préalables et ce qu'ils ne permettent pas de vérifier.
Ces différences sont logiques et correspondent à leur implémentation :
Dans une LinkedList, chaque élément est stocké en mémoire avec l'adresse du suivant et du précédent.
Dans une ArrayList, les éléments sont stockés en mémoire de manière à ce que leur position soit calculée par l'algorithme.
- Pour ajouter ou supprimer un élement en tête d'une LinkedList il suffit de modifier l'élément qui était auparavant le premier pour lui ajouter l'adresse du nouvel élément alors que dans une LinkedList tous les éléments suivants doivent être décalés, ce qui explique la grande différence de consommation CPU observée sur ces opérations.
- Pour l'accès de valeur dans une LinkedList l'algorithme part du début ou de la fin de la liste selon la position et la parcours jusqu'à tomber sur la position désirée, ce qui prends plus de temps que l'ArrayList dont la postion des élements est connue et dont il est donc très peu couteux d'accéder à n'importe quel élément. Cela explique le comportement similaire entre les Tableaux et les ArrayList ainsi que le cout CPU plus élevé pour les LinkedList.
- La consommation légerement supérieure en mémoire pour les LinkedList s'explique par le stockage en mémoire des pointeurs sur les élements précedants et suivants.
## Etude approfondie
......
NbOperations,Version,CPU,Mem
100000,ArrayListStd,0.93,49744
100000,ArrayListStd,0.92,51900
100000,ArrayListStd,0.94,54076
100000,LinkedListStd,0.10,57368
100000,LinkedListStd,0.09,53968
100000,LinkedListStd,0.10,58016
125000,ArrayListStd,1.50,56932
125000,ArrayListStd,1.49,49920
125000,ArrayListStd,1.48,54748
125000,LinkedListStd,0.10,57980
125000,LinkedListStd,0.11,51984
125000,LinkedListStd,0.09,56848
150000,ArrayListStd,2.18,53000
150000,ArrayListStd,2.19,52208
150000,ArrayListStd,2.12,54892
150000,LinkedListStd,0.11,57384
150000,LinkedListStd,0.10,56276
150000,LinkedListStd,0.09,56932
175000,ArrayListStd,2.90,51824
175000,ArrayListStd,2.87,50036
175000,ArrayListStd,2.91,57148
175000,LinkedListStd,0.10,58256
175000,LinkedListStd,0.09,56192
175000,LinkedListStd,0.11,55976
200000,ArrayListStd,3.77,54168
200000,ArrayListStd,3.81,53232
200000,ArrayListStd,3.79,49800
200000,LinkedListStd,0.10,56552
200000,LinkedListStd,0.09,54564
200000,LinkedListStd,0.10,56368
225000,ArrayListStd,4.79,56976
225000,ArrayListStd,4.81,53152
225000,ArrayListStd,4.79,55096
225000,LinkedListStd,0.10,54560
225000,LinkedListStd,0.10,56372
225000,LinkedListStd,0.10,56580
250000,ArrayListStd,5.89,52100
250000,ArrayListStd,5.97,53948
250000,ArrayListStd,5.96,51932
250000,LinkedListStd,0.09,58324
250000,LinkedListStd,0.10,63632
250000,LinkedListStd,0.11,58200
275000,ArrayListStd,7.26,57844
275000,ArrayListStd,7.18,59240
275000,ArrayListStd,7.17,52188
275000,LinkedListStd,0.10,58096
275000,LinkedListStd,0.09,61856
275000,LinkedListStd,0.10,61336
300000,ArrayListStd,8.54,54092
300000,ArrayListStd,8.57,53752
300000,ArrayListStd,8.55,53884
300000,LinkedListStd,0.11,58108
300000,LinkedListStd,0.11,58852
300000,LinkedListStd,0.09,62012
NbOperations,Version,CPU,Mem
100000,ArrayListStd,0.09,50160
100000,ArrayListStd,0.09,57184
100000,ArrayListStd,0.08,56732
100000,LinkedListStd,0.08,54040
100000,LinkedListStd,0.09,54144
100000,LinkedListStd,0.09,52152
125000,ArrayListStd,0.09,49956
125000,ArrayListStd,0.09,51700
125000,ArrayListStd,0.09,49956
125000,LinkedListStd,0.10,53928
125000,LinkedListStd,0.10,54420
125000,LinkedListStd,0.08,51920
150000,ArrayListStd,0.08,55864
150000,ArrayListStd,0.08,51748
150000,ArrayListStd,0.09,54876
150000,LinkedListStd,0.08,55732
150000,LinkedListStd,0.10,52108
150000,LinkedListStd,0.09,54008
175000,ArrayListStd,0.08,52336
175000,ArrayListStd,0.09,52288
175000,ArrayListStd,0.09,55736
175000,LinkedListStd,0.09,56248
175000,LinkedListStd,0.08,59176
175000,LinkedListStd,0.09,57512
200000,ArrayListStd,0.09,57228
200000,ArrayListStd,0.09,51932
200000,ArrayListStd,0.11,55940
200000,LinkedListStd,0.10,57740
200000,LinkedListStd,0.09,55856
200000,LinkedListStd,0.10,56324
225000,ArrayListStd,0.08,51612
225000,ArrayListStd,0.09,57284
225000,ArrayListStd,0.08,53900
225000,LinkedListStd,0.09,58020
225000,LinkedListStd,0.11,61368
225000,LinkedListStd,0.08,59124
250000,ArrayListStd,0.08,58044
250000,ArrayListStd,0.11,56984
250000,ArrayListStd,0.09,59212
250000,LinkedListStd,0.08,58208
250000,LinkedListStd,0.09,60500
250000,LinkedListStd,0.10,60372
275000,ArrayListStd,0.09,55928
275000,ArrayListStd,0.10,57824
275000,ArrayListStd,0.10,52056
275000,LinkedListStd,0.11,61996
275000,LinkedListStd,0.10,61052
275000,LinkedListStd,0.10,58404
300000,ArrayListStd,0.09,59228
300000,ArrayListStd,0.10,59292
300000,ArrayListStd,0.09,57160
300000,LinkedListStd,0.10,56204
300000,LinkedListStd,0.11,56340
300000,LinkedListStd,0.12,63232
NbOperations,Version,CPU,Mem
100000,TableauStd,0.08,54660
100000,TableauStd,0.07,51620
100000,TableauStd,0.10,51572
125000,TableauStd,0.07,55688
125000,TableauStd,0.08,58932
125000,TableauStd,0.07,52760
150000,TableauStd,0.08,51760
150000,TableauStd,0.08,51968
150000,TableauStd,0.06,51864
175000,TableauStd,0.08,49660
175000,TableauStd,0.07,56428
175000,TableauStd,0.08,55504
200000,TableauStd,0.08,53872
200000,TableauStd,0.09,59032
200000,TableauStd,0.10,51900
225000,TableauStd,0.08,52216
225000,TableauStd,0.09,54792
225000,TableauStd,0.09,53832
250000,TableauStd,0.09,55916
250000,TableauStd,0.08,53660
250000,TableauStd,0.09,49876
275000,TableauStd,0.08,53648
275000,TableauStd,0.08,53668
275000,TableauStd,0.07,53560
300000,TableauStd,0.08,54812
300000,TableauStd,0.08,54472
300000,TableauStd,0.08,56780