If(){design}else{art} Processing, le livre

9 novembre 2019

Performances comparées de Array et ArrayList

Filed under: optimisation — jean-noël Lafargue @ 13 h 47 min

Processing permet de manipuler les tableaux avec deux types de variables : les Array (tableaux « normaux » de Processing) et les ArrayList (tableaux Java). Lorsque les tableaux contiennent des variables d’un type élémentaire (int, float), et que la taille du tableau ne change jamais, on a tendance à employer les tableaux « normaux ».
Lorsque l’on recourt à des données plus complexes, comme l’objet PVector, ou des classes créées par le programmeur, et surtout lorsque l’on veut que le tableau puisse voir sa taille changer, on dit souvent qu’il vaut mieux utiliser ArrayList. Nous avons décidé d’évaluer dans quelle mesure le choix d’une ou l’autre méthode impacte les performances.
Voici deux programmes qui permettent d’effectuer une comparaison. Ces deux programmes créent des particules, et remplissent des tableaux qui finissent par contenir plus de 30 000 instances, dont chacune est individuellement appelée afin de changer de position et de s’afficher.

Voici la version avec un tableau « normal » :

poin[] allPoints;
int cx,cy, begining;

void setup(){
begining = millis();
size(640,640);
cx=width/2;cy=height/2;
allPoints = new poin[0];
}

void draw(){
background(255);
int t=millis();
poin[] newAllPoints = new poin[0];
for(poin p:allPoints){
p.avance();
if(p.alive){
newAllPoints = (poin[]) append(newAllPoints, p);
}
}
float ang=TWO_PI/frameCount;
for(float a=0;a30000){println("total time : "+(millis()-begining));noLoop();}
}

class poin{
float x,y,a;boolean alive=true;
poin(float x, float y, float a){
this.x=x;this.y=y;this.a=a;
}
void avance(){
if(x<0||y<0||x>width||y>height)alive=false;
x+=cos(a)2;y+=sin(a)2;
point(x,y);
}
}

Et voici la version avec ArrayList :

ArrayList allPoints;
int cx,cy, begining;

void setup(){
begining = millis();
size(640,640);
cx=width/2;cy=height/2;
allPoints = new ArrayList(0);
}

void draw(){
background(255);
int t=millis();
ArrayList newAllPoints=new ArrayList();
for(poin p:allPoints){
p.avance();
if(p.alive){
newAllPoints.add(p);
}
}
float ang=TWO_PI/frameCount;
for(float a=0;a30000){println("total time : "+(millis()-begining));noLoop();}
}

class poin{
float x,y,a;boolean alive=true;
poin(float x, float y, float a){
this.x=x;this.y=y;this.a=a;
}
void avance(){
if(x<0||y<0||x>width||y>height)alive=false;
x+=cos(a)2;y+=sin(a)2;
point(x,y);
}
}

Sur mon ordinateur (mais ce sera différent sur un ordinateur de puissance différente), la première méthode est lente puisqu’il faut plus de 2000 millisecondes (deux secondes) pour traiter 30162 instances. Avec la seconde méthode, le même nombre d’instances est traité en moins de 400 millisecondes (4/10e de seconde).

Le tableau ArrayList l’emporte donc ici haut la main en se montrant plus de cinq fois plus rapide !

Powered by WordPress