différence de vitesse java VS c++
Bonjour,
J'ai recodé un programme de traitement d'image du c++ vers le java.
Pour une image de 512x512, le programme c++ met moins de 30 secondes, alors que le programme java ne finit pas au bout d'une heure.
Tous les algos du programme sont censés être linéaires ou quasi-linéaire, mais peut-être ai-je fait une erreur lorsque j'ai recodé en java.
Je ne veux pas du tout discuter duquel des deux langages est le meilleur.
Ce que je veux précisément savoir c'est si EN THÉORIE, il est possible d'observer ce genre de situation avec des programmes qui font strictement la même chose dans chaque langage.
Qu'il y ait des différences ok, mais là la différence me semble trop importante (30 sec VS des heures).
Merci pour votre aide.
voici précisément mon problème
Merci à tous pour vos réponses !
Désolé pour le retard mais ça m'a pris du temps pour identifier mon problème, mais je ne l'ai pas résolu...
Le programme est long mais j'ai extrait la partie du code qui pose problème pour vous la montrer.
Je travaille avec des arbres dont les noeuds regroupent des pixels voisins.
L'idée c'est de stocker, pour chaque pixel, les coordonnées de son pixel parent.
Les coordonnées sont stockées dans la classe Coords2D, et la classe Image2DCoords2D représente la carte des parents (c'est juste un tableau de Coords2D).
Mon problème se situe dans la classe Filter_. J'utilise une fonction zFindRoot pour trouver la racine de chaque sous-arbres. L'idée de cette fonction est que le parent d'une racine est la racine elle-même. Du coup j'utilise la récursivité, plus précisément je demande à la machine de me renvoyer le parent, puis le parent du parent... etc... jusqu'à ce que le parent du pixel soit égal au pixel lui-même.
Pour savoir si les coordonnées sont les même, j'utilise la fonction sameCoords.
Ma fonction zFindRoot est terriblement lente en java, alors qu'en c++ il n'y a aucun problème. De plus, cette fonction me cause un stack overflow si je n'augmente pas la taille de la pile (ce que je fais et peut-être que le problème est là, je ne sais pas).
Il y a mon implémentation dans la suite du message. J'ai retiré tout ce qui n'est pas absolument nécessaire. Il y a quelques lignes certes mais c'est plutôt facile à lire. Je rappelle juste qu'une image est représentée par un tableau de valeurs, et qu'on accède à la valeur du pixel par l'indice y * largeurDELImage + x.
Je vous remercie d'avance, peut-être comprendrez vous pourquoi mon code est si lent en java alors qu'en c++ c'est rapide.
C'est sûrement encore une erreur à la con, je manque d'expérience et ne suis pas vraiment un "rapide" comme on dit.
Voici les fonctions sameCoords et zFindRoot de la classe Filter_
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
import utilities.Coords2D;
import utilities.Image2DCoords2D;
public class Filter_ implements PlugIn {
/**
* Tests if two Coords2D are equals.
*/
public static boolean sameCoords(Coords2D coords1, Coords2D coords2) {
return coords1.getX() == coords2.getX() && coords1.getY() == coords2.getY();
}
/**
* Finds the temporary root during tree construction.
*/
public static Coords2D zFindRoot(Image2DCoords2D image, Coords2D coords) {
if (sameCoords(image.getValue(coords), coords)) {
return image.getValue(coords);
} else {
return (zFindRoot(image, image.getValue(coords)));
}
}
} |
Voici la classe abstraite Image2D :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
package utilities;
abstract class Image2D {
// dimensions
public int borderSize;
public int width;
public int height;
public int widthWithBorder;
public int heightWithBorder;
} |
Voici la classe Image2DCoords qui est la carte des parents :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
|
package utilities;
import utilities.Image2D;
import utilities.Coords2D;
public class Image2DCoords2D extends Image2D {
public Coords2D[] image;
/**
* Creates an Image2DCoords2D.
*/
public Image2DCoords2D(int width, int height, int borderSize, Coords2D value) {
// border
this.borderSize = borderSize;
// original dimensions
this.width = width;
this.height = height;
// dimensions with the border
this.widthWithBorder = width + 2 * borderSize;
this.heightWithBorder = height + 2 * borderSize;
// coordinates
int x = value.getX();
int y = value.getY();
// the image with the border
fill(x, y);
}
/**************************************************************************/
/**
* Fills the Image2DCoords2D with the specified value.
*/
public void fill(int x, int y) {
this.image = new Coords2D[this.widthWithBorder*this.heightWithBorder];
for (int u=0; u<this.widthWithBorder; u++) {
for (int v=0; v<this.heightWithBorder; v++) {
this.image[v*this.widthWithBorder+u] = new Coords2D(x, y);
}
}
}
/**************************************************************************/
/**
* Gets the value of a pixel.
*/
public Coords2D getValue(int x, int y) {
return this.image[y*this.widthWithBorder+x];
}
/**************************************************************************/
/**
* Gets the value of a pixel.
*/
public Coords2D getValue(Coords2D coords) {
return this.image[coords.getY()*this.widthWithBorder+coords.getX()];
}
/**************************************************************************/
/**
* Sets the value of a pixel.
*/
public void setValue(int x, int y, Coords2D value) {
this.image[y*this.widthWithBorder+x] = value;
}
/**************************************************************************/
/**
* Sets the value of a pixel.
*/
public void setValue(Coords2D coords, Coords2D value) {
this.image[coords.getY()*this.widthWithBorder+coords.getX()] = value;
}
} |
Enfin voici la classe Coords2D :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
package utilities;
public class Coords2D {
// x first and then y
public int coords[] = new int[2];
// border (dirty)
public int borderSize = 3;
/**
* Creates a Point2D.
*/
public Coords2D(int x, int y) {
this.coords[0] = x;
this.coords[1] = y;
}
/**
* Returns the column number.
*/
public int getX() {
return this.coords[0];
}
/**
* Returns the row number.
*/
public int getY() {
return this.coords[1];
}
/**
* Sets the column number.
*/
public void setX(int x) {
this.coords[0] = x;
}
/**
* Sets the row number.
*/
public void setY(int y) {
this.coords[1] = y;
}
/**
* For println.
*/
public String toString() {
return "("+ (getY()-this.borderSize) + "," + (getX()-this.borderSize) + ")";
}
} |
Voilà ! Merci à tous d'avance pour vos réponses, ou juste pour avoir lu mon post.