IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

différence de vitesse java VS c++


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2009
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 5
    Par défaut 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.

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Oui, c'est même très courant quand on passe d'un langage que l'on maitrise à un langage que l'on ne maitrise pas. Prend ton programme, annote le avec la justification de la linéarité de l'algorithme et poste le, on te dira où tu t'es fourvoyé. Tu utilise probablement une api ou des méthode que tu pense linéaires dans l'api et qui ne le sont pas. Si tu manipule des objets type BufferedImage ou Graphics, sache que ce qui se trouve derrière est loin d'être perfomant, ça ca applique des règles de correction de couleur pour permettre un affichage à l'écran et changer la couleur d'un seul pixel dans un BufferedImage implique beaucoup de calculs derrière.

  3. #3
    Membre Expert
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Par défaut
    Disons que là comme ça, sans le code sous les yeux, j'aurai tendance à dire que les performances devraient être à peu près identiques...

    Sauf que la gestion de la mémoire n'est pas la même entre les deux univers, et que certaines pratiques qui fonctionnent en C++ peuvent avoir des conséquences désastreuses en Java.
    Tu utilises des librairies externes ou tout le code vient de toi?

  4. #4
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 326
    Billets dans le blog
    12
    Par défaut
    Si tu fais uniquement du calcul, le temps entre un programme Java et C++ devrait plus ou moins être similaire, donc si un programme C++ ne dure que 30 secondes et un programme Java dure des heures c'est qu'il y a forcément un problème.
    Si tu utilises beaucoup la récursivité, il est fort probable que tu vas avoir des problèmes en Java (Java n'aime pas la récursivité). N'hésite pas à poster tes 2 codes pour qu'on puisse essayer d'identifier le problème.
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  5. #5
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 688
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 688
    Par défaut
    Il y a souvent une différence sensible entre Java et C, mais en effet si tu passe de quelques secondes à quelques heures, il y a manifestement un soucis sur la manière dont a été fait le code Java.
    Malheureusement, si tu ne nous le montres pas on ne pourra pas t'aider.

  6. #6
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Par défaut
    +1 avec ce qui a été dit.

    Si en java tu utilises un BufferedImage et n'accèdes pas directement au DataBuffer, alors les I/O sont très lentes, surtout si tu utilises getRGB. (je fais du traitement d'images en Java)

    Ensuite, tu peux avoir un GROS écart entre C++ et Java, si le programme C++ utilise des optimisation matérielles comme du SSE2 ou de l'auto-vectorisation. Et ça se peut facilement sur des traitements linéaires.
    Mais en aucun cas, tu ne peux passer de 30 secondes à plus d'une heure.
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2009
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 5
    Par défaut 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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

Discussions similaires

  1. Différence entre API Java EE et API Java SE
    Par lamine87 dans le forum Java EE
    Réponses: 4
    Dernier message: 20/02/2013, 21h39
  2. Différence base64_encode entre Java et PHP
    Par JuSirap dans le forum Langage
    Réponses: 2
    Dernier message: 13/06/2012, 10h17
  3. syntaxe pointeur ou tableau: différence de vitesse ?
    Par supernewbienoob dans le forum Débuter
    Réponses: 14
    Dernier message: 16/12/2010, 09h40
  4. Différences entre Eclipse Java JEE RCP
    Par bailamos dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 03/11/2009, 23h04
  5. Différence flash et java ?
    Par jerem488 dans le forum Langage
    Réponses: 2
    Dernier message: 12/05/2007, 16h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo