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

Langage Delphi Discussion :

Lecture et modification de gros fichier texte la plus rapide possible


Sujet :

Langage Delphi

  1. #21
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    encore une petite chose que tu dois pouvoir utiliser...SetTextBuf()

    la taille du buffer par défaut est de 128 bytes, une lecture par bloques de 4K peut rendre les choses plus rapides.
    Effectivement, je ne connaissais pas non plus;
    Par contre, j'ai essayé et cela produit des erreurs de lecture systématiquement. J'ai aussi essayé avec [0..2047] mais sans résultats.
    Mais je dois avouer que je maitrise très mal cette fonction.

    C'est quand même bizarre ces fonctionnalités qui ne se trouvent pas dans l'aide (ou alors j'ai mal cherché) alors qu'elles offrent un plus inestimable

  2. #22
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par TicTacToe Voir le message
    si les fichiers font 3 000 000 de lignes (donc largement au dessus des prévisions de taille de fichier), cela fait 110Mo à prendre en mémoire... c'est pas le Pérou non plus
    Euh 3 000 000 de ligne c'est un "petit" fichier
    Par exemple, je risque bientôt d'avoir des fichiers de 44 000 000 de lignes si mes calculs sont exacts. Donc là, c'est le Pérou et l'Amérique du Sud toute entière
    Mais c'est à essayer.

  3. #23
    Membre expert
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Points : 3 575
    Points
    3 575
    Par défaut
    Citation Envoyé par Pedro
    J'ai fait un programme de conversion de format de données.
    Il lit un très gros fichier texte (qui dépasse allègrement le million de lignes).
    Je suis parti sur cette base
    44 000 000 c'est loin de cela

    En tout cas, même en ligne à ligne, il faut à mon avis bannir les conversions inutiles. Les ReadLn(...) et WriteLn(...) c'est bien, mais finalement ca te converti (dans les 2 sens) les 3 réels ce qui n'est absolument pas indispensable.
    Mieux vaut traiter toit même la chaine de caractère et ne faire que le strict minimum au niveau conversion.

    De plus pour la conversion du 'I', il vaut mieux un table de correspondance, vu les valeurs, il y a pas plus rapide je pense

    La table de coresspondance aurait d'ailleurs pu être un tableau de chaine et non d'entier maintenant que j'y pense (voir le code)... et hop une conversion en moins !

  4. #24
    Membre actif
    Profil pro
    DEV
    Inscrit en
    Août 2006
    Messages
    182
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : DEV

    Informations forums :
    Inscription : Août 2006
    Messages : 182
    Points : 211
    Points
    211
    Par défaut
    Citation Envoyé par Pedro Voir le message
    Effectivement, je ne connaissais pas non plus;
    Par contre, j'ai essayé et cela produit des erreurs de lecture systématiquement. J'ai aussi essayé avec [0..2047] mais sans résultats.
    Mais je dois avouer que je maitrise très mal cette fonction.

    C'est quand même bizarre ces fonctionnalités qui ne se trouvent pas dans l'aide (ou alors j'ai mal cherché) alors qu'elles offrent un plus inestimable
    Ces fonctionnalités sont dans l'aide
    Ensuite pour les erreures de lecture voici ce que l'aide dit

    SetTextBuf peut être appelé immédiatement après Reset, Rewrite ou Append, mais vous ne devez jamais l'appliquer à un fichier ouvert.

    Si vous appelez SetTextBuf sur un fichier ouvert après qu'une opération d'E/S ait eu lieu, vous risquez de perdre les données du tampon.

    Delphi ne peut garantir que le tampon existera pendant toute la durée des opérations d'E/S sur le fichier. Une erreur commune consiste à affecter une variable locale au tampon, puis à utiliser le fichier en-dehors de la procédure dans laquelle a été déclaré le tampon.

  5. #25
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par DragonHeart
    Ces fonctionnalités sont dans l'aide
    Je ne parlais pas SetTextBuf mais plutôt des possibilités avec ReadLn et WriteLn
    Citation Envoyé par DragonHeart
    Ensuite pour les erreures de lecture voici ce que l'aide dit
    Oui j'avais vu mais j'ai bien respecté l'ordre: J'appelle SetTextBuf juste après Reset J'ai aussi essayé juste avant mais le même problème se pose.
    C'est au niveau de la conversion que ça plante. (Erreur: "invalid numeric output")

  6. #26
    Membre expert
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Points : 3 575
    Points
    3 575
    Par défaut
    Je reviens à la charge pour te soumettre une idée si tu recherches vraiment la performance.

    Je ne sais pas quel sera à peu près la répartition des masses de tes fichiers.
    Selon,
    - si 44 MLignes est une taille régulière, mieux vaut implémenter uniquement l'accès ligne à ligne
    - si 44 est un pic, et que la moyenne c'est plutot des fichiers jsuqu'à 10MLignes (prise de moins de 400Mo en mémoire), tu peux jongler avec les 2 méthodes, et choisir la bonne en fonction de la taille du fichier initiale. Tu peux changer ce curseur de Perf/Mém en fonction de la mémoire de la machine éventuellement.

    enfin, c'était une idée

  7. #27
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par TicTacToe
    Je suis parti sur cette base
    44 000 000 c'est loin de cela
    J'aurais du dire autre chose que "allègrement "alors
    Citation Envoyé par TicTacToe
    Je ne sais pas quel sera à peu près la répartition des masses de tes fichiers.
    Bah en fait c'est très variable. Ca peut aussi largement dépasser les 44 millions (je ne connais pas la limite supérieure), revenir à 1 million, etc. On pourrait dire que 44 millions est une moyenne mais bon...

  8. #28
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    l'autre question importante est : est-ce que le temps de traitement est important ?

    l'avantage du REadLn/WriteLn c'est que c'est très simple à mettre en oeuvre, c'est très peu consommateur en mémoire et ça fonctionnera quelque soir la taille du fichier.

    tout charger dans un TStringList me parait la plus mauvaise solution, car le LoadFromFile place une copie du fichier en mémoire et l'affecte par SetTextStr() qui va faire un découpage de chaque ligne.

    il serait probablement intéressant de tester (encore une fois si le temps d'execution est important) en travaillent sur un buffer de taille "suffisante"

    en pseudo code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     while RemplirBuffer=True do begin
      TrouverFinDeLigne;
      ExtraireDernierEntier;
      GenererNouvelleLigne;
      EcrireNouvelleLigne;
      DecalerBuffer;
     end;

  9. #29
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    l'autre question importante est : est-ce que le temps de traitement est important ?
    Oui c'est le paramètre le plus important. Normalement, le poste qui fera le traitement a beaucoup de ressources Ce qui m'intéresse, c'est optimiser le processus au maximum.
    L'idée de'un tableau de correspondance de TicTacToe me séduit Je vais voir ce que ça donne.

  10. #30
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    alors continuons dans les hypothèses...

    le fichier, tu ne peux pas l'avoir sous un autre format tant qu'à faire ?

    s'il était compressé, ça donne de très bon temps de lecture, car la décompression est plus rapide que la lecture disque...mais c'est surtout sensible sur de très gros fichiers.

    ce que je n'aime pas aussi dans l'usage du TStringList c'est que ça prend bcp d'allocation de mémoire, et ça aussi c'est lent. travailler sur un buffer de taille fixe sera plus efficace de ce point de vue.

  11. #31
    Membre expert
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Points : 3 575
    Points
    3 575
    Par défaut
    C'est vrai qu'il y a plusieurs partie à optimiser, et au vue des temps constaté, la partie traitement est aussi importante que la partie chargement/déchargement (enfin moindre mais on peut grapiller quand même).

    Dans le chargement, effectivement comme Paul TOTH le signal, un chargement d'un fichier compressé + décompression est plus rapide que le fichier brut (surtout pour ce genre de texte).
    -> le problème à mon avis, ce fichier doit provenir d'une autre source et est 'as in', donc s'il faut le compresser avant le traitement il y aura pas trop d'avantage. (enfin sauf si le prog maitre est maitrisable...)

    Pour le TStringList, c'est OK, il ne faut pas l'utiliser si les fichiers dépasse le 300/400Mo (mais la mémoire est là pour ca, pour être utilisée et si c'est la performance est prioritaire pourquoi s'en priver sauf autres contraintes...).
    Si les fichiers sont plus petits, le gain annoncé par rapport à l'autre méthode est multiplié par 3 quand même... (mais sans les optimisations de traitement il est vrai)

    Pour la méthode général je pense qu'il faut utiliser la méthode classique de fichier, celle de Paul Toth, mais SANS lire chaque composante.

    Se débrouiller pour lire par buffer de taille maximum (la mémoire maxi que l'on décide. par cran de 50Mo par exemple). Plus on fera des gros bloc, moins il y aura d'accès puisque là, la lecture et l'écriture sont entrelacée (même avec le cache, le fichier est destiné à être lu une seule fois pour la conversion)
    Plus les blocs seront gros, plus on tendra vers les temps du TStringList.

    Lire la chaine de caractères de chaque ligne en mémoire (pas composante par composante), traiter manuellement la dernière composante (en gros il n'y a qu'UNE conversion de entier à str), tout le reste n'est que parcours de chaines et là tout est vraiment bien optimisé du coté de delphi. (voir l'exemple que je fournis)

    voila, je partirai dans ce sens pour atteindre les meilleures vitesses.

  12. #32
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    En ce qui concerne ce fichier:
    Je suis géomètre.
    Ce fichier contient les observations (mesures) brutes d'un appareil appelé scanner 3D. Cet appareil balaye une zone avec un faisceau laser et prend 500 000 points/seconde.
    Jusque là OK.
    Seulement, ce scanner est de marque Leica et nos logiciels sont Trimble (marque concurrente).
    Il faut donc faire un transfert.
    Chaque point est défini par ses coordonnées dans l'espace et son intensité I. Chez Leica, l'intensité est sur 12 bits, alors que chez Trimble, elle est sur 8 d'où la conversion.
    Pour l'instant, on fait des exports en ASCII pour faire la jonction entre les 2 types de données. Il y a également pleins d'autres format d'export/import dispos mais je ne connais pas leur structure et vous imaginez bien qu'un appareil à la distribution aussi confidentielle ne propose pas de documentation digne de ce nom.
    Impossible également de trouver ne serait-ce qu'un seul format proposé à l'export.
    Donc, pour l'instant, fichier texte. Plus tard, on découvrira peut-être un format miracle. Inutile de dire que je ne contrôle absolument rien sur la sortie des données...

    Evidemment, la taille du fichier texte est directement lié au nombre de points relevés sur le terrain. Par contre, on peut connaitre le nombre maximum de points (donc de la taille du fichier). Je ne la connais pas encore mais je vérifierai la prochaine fois qu'on sort cet appareil (demain normalement).
    Vous comprendrez qu'avec un appareil capable de cette cadence, les fichiers enflent très vite

    Sinon, faire une lecture par bloc et rester sur l'utilisation des TStringList me parait aussi une alternative intéressante.
    Il faut que je vérifie tout ça ce soir...

    Merci en tout cas de l'intérêt que vous portez à mon problème

  13. #33
    Membre expert
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Points : 3 575
    Points
    3 575
    Par défaut
    Effectivement, donc ca confirme que le zip faut oublier.

    Après des tests, et bien je suis assez surpris, mais le TStringList.Load() dois faire pas mal de trucs derriere car effectivement, il devient plus lent que le ReadLn avec un buffer maxi (65Ko).

    sur ma machine et pour 1.5 MLignes

    Méthode TStringList avec conversion optimisée -> 2.42 sec
    Méthode ReadLn, en bloc 64Ko sans conversion optimisée -> 2.84 sec (7 sec sans lecture par bloc...)
    Méthode ReadLn, en bloc 64Ko avec conversion optimisée -> 1.03 sec

    avec évidemment un gain mémoire pour le ReadLn incommensurable.
    Donc bien vu Paul Toth pour le ReadLn(), j'aurais pas cru autant.
    L'optimisation de la conversion prend toute son importance par contre et divise pratiquement par 3 le traitement global

    ps: lien mis à jour pour les tests:
    http://tictactoe.developpez.com/temp/pedro.zip

  14. #34
    Membre averti
    Inscrit en
    Octobre 2005
    Messages
    338
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 338
    Points : 383
    Points
    383
    Par défaut
    bonsoir
    juste pour info j'ai essayé le prog de Tictactoe et, la taille du fichier bouton2 est différent des deux autres (47.5 pou 51.9 Mo ?).
    par contre je suis impressionné que l'on puisse écrire ça en deux secondes (ça fait 2 heures que j'essai de faire un bout de code correct, pour lire par bloc et traiter en binaire...)

    à+

  15. #35
    Membre expert
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Points : 3 575
    Points
    3 575
    Par défaut
    Citation Envoyé par banban54 Voir le message
    bonsoir
    juste pour info j'ai essayé le prog de Tictactoe et, la taille du fichier bouton2 est différent des deux autres (47.5 pou 51.9 Mo ?).
    par contre je suis impressionné que l'on puisse écrire ça en deux secondes (ça fait 2 heures que j'essai de faire un bout de code correct, pour lire par bloc et traiter en binaire...)

    à+
    normal, la méthode du bouton 2 convertis les composantes réelles:
    string -> réel -> string

    du coup, 1.20 devient 1.2
    -> des octets en moins

  16. #36
    Membre averti
    Inscrit en
    Octobre 2005
    Messages
    338
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 338
    Points : 383
    Points
    383
    Par défaut

    à+

  17. #37
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Salut

    Bon je crois que je tiens le bon bout
    Sur un fichier de test de 1 205 779 lignes, le processus se finit en 2.25 secondes

    Soit, à peine plus de trois minutes sur un fichier de 100 000 000 de points!
    Pour info, mon tout premier programme vite fait mettait presque 20 minutes pour convertir 10 000 000 de points

    C'est pas trop mal étant donné que l'interface se modifie pendant ce temps (ProgressBars), que j'ai laissé la possibilité d'interrompre le traitement et que je parcours le fichier complètement au début pour compter les lignes.

    Pour info, la meilleure méthode de TicTacToe le fait en 1.36 secondes (quel talent )

    Sinon, pour une énième optimisation, j'ai modifié la méthode de TicTacToe de Modification de la ligne comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
         IPos := PosEx(' ', SChaine, PosEx(' ', SChaine, PosEx(' ', Trim(SChaine), 1) + 1) + 1);
         Result := Copy( SChaine, 1, IPos ) +
          FValues[ StrToInt( Copy( SChaine, IPos + 1, Length( SChaine ) - IPos + 1 ) ) ];
    Soit 2 assignations en moins des millièmes de secondes de gagnés Par exemple, sur mon fichier test (1205779 points donc), on gagne presque une demi seconde.
    Je crois que je peux passer en résolu

    Merci encore à tous pour votre aide

    [EDIT]
    J'ai même pas dit ce que j'ai utilise
    • SetTextBuf pour fIn et fOut de Paul
    • La méthode de TicTacToe pour la conversion et la lecture
    • Un tableau de correspondance
    Voici mon programme final (du moins pour ce soir )
    http://pedro.developpez.com/temp/LeicaToTrimble.zip

  18. #38
    Membre expert
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Points : 3 575
    Points
    3 575
    Par défaut
    bien vu pour les assignations, en général je préfère tout découper au début en tout cas pour pas m'emmeler les pinceaux

    sinon, je pense que tu peux gagner encore un peu en remplacant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Length( SChaine ) - IPos + 1
    tout simplement par ,

    car que j'avais fais un test avec des shortstring.

    la fonction copy(...) n'ira pas plus loin que le bout de la chaine (je crois que c'est rapidement vérifiable dans le code asm de la fonction) et donc... un appel de fonction en moins....

    on grapille on grapille

  19. #39
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par TicTacToe
    bien vu pour les assignations, en général je préfère tout découper au début en tout cas pour pas m'emmeler les pinceaux
    Oui normalement moi aussi J'ai d'ailleurs eu du mal à tout rassembler
    Citation Envoyé par TicTacToe
    sinon, je pense que tu peux gagner encore un peu en remplacant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Length( SChaine ) - IPos + 1
    tout simplement par
    Bien vu , je gagne encore un dixième de seconde...
    Si ça continue comme ça, le traitement va finir par être instantané

    Citation Envoyé par banban54
    par contre je suis impressionné que l'on puisse écrire ça en deux secondes
    Ouais j'avoue avoir été plutot impressionné lorsque TicTacTioe m'a sorti sa première version qui faisait quelques secondes pour 1 500 000
    Citation Envoyé par banban54
    (ça fait 2 heures que j'essai de faire un bout de code correct, pour lire par bloc et traiter en binaire...)
    Bon courage Tiens-moi au courant si tes recherches aboutissent
    PS: j'ai mis le ZIP à jour

  20. #40
    Membre expert
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Points : 3 575
    Points
    3 575
    Par défaut
    juste un truc mais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      for i := -2048 to 2047 - 1 do
        FValues[i] := IntToStr(Trunc(256 * (i + 2048) / 4096));
    il y a pas le -1 (habituel) pour 2047
    pour 2047 ca te donnerait n'importe quel valeur

    [Mode pinaille]
    sinon "(i+2048) shr 4" marche aussi mais c'est moins parlant.
    [/Mode pinaille]

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 3 PremièrePremière 123 DernièreDernière

Discussions similaires

  1. lecture de (très) gros fichiers texte
    Par Paul18 dans le forum Scilab
    Réponses: 7
    Dernier message: 14/06/2011, 23h05
  2. Problème lecture gros fichier texte
    Par UnnamedBoy dans le forum Entrée/Sortie
    Réponses: 7
    Dernier message: 22/02/2008, 12h13
  3. [VBA-E] Ecrire un fichier texte le plus rapidement possible
    Par spileo dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 13/09/2007, 21h51
  4. [C#]Lecture gros fichier texte
    Par kekesilo dans le forum Windows Forms
    Réponses: 5
    Dernier message: 20/05/2006, 14h58
  5. [VBA-E]Telecharger un gros fichier texte
    Par Elstak dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 10/04/2006, 10h16

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