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

SL & STL C++ Discussion :

Tableaux associatifs fixes


Sujet :

SL & STL C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut Tableaux associatifs fixes
    Bonjour,

    L'application sur laquelle je travaille utilise beaucoup de tableaux associatifs. Certains d'entre eux sont très gros (le principal pourrait avoir, en régime de croisière plusieurs centaines de milliers, peut être un million d'entrées), d'autres sont plus petits (quelques milliers d'entrées), mais tous sont très sollicités à l'exécution.

    Ces tableaux associatifs partagent tous une caractéristique commune : on n'y fait ni insertion, ni suppression. Ils sont lus au démarrage de l'appli (ou la première fois qu'on en a besoin), dans des fichiers produits par une autre application (je peux en changer le format si nécessaire). Aujourd'hui ils sont indexés par des string.

    En première approche, j'ai utilisé des map, que je charge à partir de fichiers triés selon la clef. Quelque chose comme

    Et je fais appel à find() pour les recherches. Sur un fichier déjà trié, le chargement se fait en temps linéaire, et les recherches en temps logarithmique.

    Après réflexion, il me semble qu'un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vector<pair<string,MonType> >
    trié dans l'ordre des clefs, et une recherche binaire, fonctionnerait mieux. A priori, le chargement est aussi linéaire (mais certainement de coefficient dominant plus faible que pour la map), la recherche aussi logarithmique, et l'empreinte mémoire sans doute plus faible...

    Est ce bien le cas?

    Du coup, je me demande si je peux améliorer cela...

    J'ai réfléchi à deux solutions, par forcément exclusives l'une de l'autre

    1- une réindexation de mes codes, destinée à remplacer les string par des entiers. Les recherches binaires effectuant des comparaisons assez nombreuses (entre 10 et 20 par recherche dans mon cas), utiliser une comparaison d'entier devrait significativement améliorer le temps de recherche, et également réduire l'empreinte mémoire de mon tableau...

    2- l'utilisation d'un tableau haché (hash_map), les codes de hachage étant précalculés dans le fichier initial (pour éviter de les refaire au chargement), mais du coup, je me demande si cela n'est pas strictement équivalent à ma réindexation...

    Qu'en pensez vous? Qu'utiliseriez vous?

    (je précise que je suis sous Borland Builder 6, que ma STL est une STLPort, et que seuls des bouts de boost fonctionnent, en revanche, je n'aurais aucun complexe à me lancer dans un codage d'algorithme spécifique, cette recherche est réellement le coeur de l'application).

    Merci d'avance
    Francois

  2. #2
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Un vecteur de pair risque de poser problème pour les grands tableaux, car il demande à ce que la mémoire soit continue.

    Je n'ai pas trop compris comment tu comptes remplacer des strings par des entiers ?

    Est-ce que tu vas souvent chercher les mêmes données ? Il y a des structures d'arbres comme une map mais qui vont réordonner des données à chaque interrogation de telle manière que les demandes fréquentes soient plus proches du sommet.

    Une hashmap, pourquoi pas, mais en faisant bien attention d'éviter les doublons.
    Tes strings sont-ils semblables d'une exécution à l'autre ? Tu pourrais dans ce cas faire un test de la fonction de hash voir ce qu'elle vaut ?
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  3. #3
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Un vecteur de pair risque de poser problème pour les grands tableaux, car il demande à ce que la mémoire soit continue.
    Effectivement... En fait, je me rend compte qu'il n'est pas nécessaire de stocker ensembles les clefs et les valeurs, mais juste d'associer à chaque clef "quelque chose" qui permettre de retrouver la valeur correspondante...

    On pourrait donc avoir soit un vecteur de pair<clef,adresse> (l'adrresse étant un indice dans le tableau des valeurs), soit même juste un vecteur de clefs, en utilisant la position renvoyée comme l'indice dans un vecteur de valeurs...

    Merci beaucoup pour la suggestion...

    Citation Envoyé par JolyLoic Voir le message
    Je n'ai pas trop compris comment tu comptes remplacer des strings par des entiers ?
    En fait, les string qui me servent de clefs sont assez peu utilisées pour elles mêmes (essentiellement lors de sauvegardes), et généralement utilisées comme index dans mes tables associatives. Dans la mesure où mes tables ne bougent pas d'une éxécution à l'autre, je me disais que je pourrais peut être tout réindexer avant l'exécution, en associant à chaque string un entier unique, et en remplaçant, partout où je peux, le string par l'entier... Ca ressemble à la notion d'index de table dans les Bases de Données, si tu veux.

    De cette façon mes recherches se font sur des entiers, au lieu des strings, mais je conserve dans un coin la correspondance "index clef", pour les quelques cas ou je dois utiliser les clefs...

    Citation Envoyé par JolyLoic Voir le message
    Est-ce que tu vas souvent chercher les mêmes données ? Il y a des structures d'arbres comme une map mais qui vont réordonner des données à chaque interrogation de telle manière que les demandes fréquentes soient plus proches du sommet.
    Tu m'intéresses ! En fait, je pense que je vais avoir à peu près 500 000 entrées dans le tableau principal, mais qu'à l'éxécution, il sera rare qu'on n'ait besoin de plus d'une centaine. En fait, je sais même assez précisément (à l'exécution) quelles entrées vont revenir (certaines opérations utilisent des entrées juste une fois, d'autres indiquent qu'une entrée va souvent servir...)

    En y repensant, je suis même probablement capable de classer a priori mes variables en fonction de leur fréquence d'utilisation... Peut on fabriquer une map qui prenne ces éléments en compte?

    Une petite référence livresque me serait bien utile là?

    Citation Envoyé par JolyLoic Voir le message
    Tes strings sont-ils semblables d'une exécution à l'autre ? Tu pourrais dans ce cas faire un test de la fonction de hash voir ce qu'elle vaut ?
    Oui, c'est en fait un peu ce qui m'a retenu jusqu'ici, le fait de devoir trouver une fonction de hachage valable...

    Francois

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par fcharton Voir le message
    Une petite référence livresque me serait bien utile là?
    http://en.wikipedia.org/wiki/Splay_tree
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Merci beaucoup!

    Francois

  6. #6
    Invité
    Invité(e)
    Par défaut
    J'ai fait des essais toute cette semaine avec des maps de quelques dizaines de milliers d'éléments (parfois plus), indexées soit par des int soit par des string...

    En gros, je les charge à partir de fichiers déjà triés (le manuel me dit que cela garantit de meilleurs temps de chargement, enfin je crois), et je les utilise pour des recherches.

    Je les ai comparées à une implémentation utilisant deux vecteurs, un trié pour les clefs, l'autre pour les valeurs, et un opérateur[] surchargé utilisant la fonction lower_bound().

    Ma conclusion du moment est : pas de maps. En gros, le chargement des maps est environ 8 fois plus lent que celui des vecteurs, et la recherche même pas plus rapide. D'autres ont ils essayé et rencontré se problème, ou y aurait il un gros piège dans lequel je suis tombé (ca me ressemblerait...)?

    Du coup, j'ai une question annexe : la structure que j'utilise a grosso modo cette forme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    template<typename S,typename T> class MaMappe {
      vector<S> Idx;
      vector<T> Data;
    }
    Idx contient les clefs, Data les données. De temps en temps, il peut m'arriver d'avoir à réordonner une telle structure. Je sais trier mes clefs avec sort, bien sur, mais comment faire pour réordonner automatiquement Data (sans avoir à recopier les données...)?

    Dans le même ordre d'idées, y a-t-il un moyen simple (dans la STL) pour, au lieu de trier explicitement les données d'un vecteur, construire un indice permettant de parcourir ce vecteur dans l'ordre de tri? Un paramètre à passer à sort(), une astuce comme cela?

    Merci d'avance
    Francois

Discussions similaires

  1. Définition "inline" de tableaux associatifs.
    Par Blustuff dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 29/03/2010, 13h49
  2. Tableaux associatifs et requêtes
    Par LFC dans le forum SGBD
    Réponses: 5
    Dernier message: 28/06/2006, 11h11
  3. Réponses: 9
    Dernier message: 13/06/2006, 21h52
  4. [8i] tableaux associatifs de VARCHAR2
    Par Magnus dans le forum Oracle
    Réponses: 2
    Dernier message: 26/01/2006, 16h41
  5. [Collections]Tableaux associatifs
    Par sheura dans le forum Collection et Stream
    Réponses: 7
    Dernier message: 18/12/2005, 14h10

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