Exemple d'assistance technique

Mission :

Une application écrite en C++ sous Linux à l'aide de la STL (Standard Template Library) s'exécutait beaucoup trop lentement et utilisait trop de mémoire. J'ai effectué une analyse du code et écrit un rapport dont voici quelques extraits.

Les conseils ont été suivis et les performances ont été améliorées dans la proportion prévue (temps divisés par 200).

Feuille de temps jointe à la facture :

Date Heures Motif
23-août 3 recherche d'informations sur implémentation actuelle avec ...
24-août 2 lecture des documents complémentaires transmis par ...
28-août 1 réunion avec ... et ...
01-sept 1 écriture rapport
total 7  

Conseil pour améliorer le temps d'exécution :

Modifier l'implémentation de la table des TEs

Cette table est implémentée sous forme de liste. La recherche d'un TE est donc proportionnelle au nombre de TEs.

En utilisant une map, le temps sera proportionnel à Log(N).

Estimation:

  • hypothèses : 240 000 éléments , un accès disque permet d'accéder à 100 TEs:
  • La recherche par liste prend en moyenne 120 000 comparaisons et 1200 accès disque.
  • La recherche dans une map prend en moyenne 18 comparaisons et 18 accès disque.
  • Si toute la table était en mémoire, le gain de performances est un facteur 10 000. Un temps de recherche de 1 seconde passe à 100 microsecondes
  • La table ne sera pas en mémoire, donc le gain de temps dépendra surtout du nombre d'accès disque.
  • Avec un temps moyen d'accès de 10 ms, 1 200 accès disque prennent 12 secondes. Ce temps d'accès passera à 180 millisecondes, soit un facteur 66.

Je pense que le gain probable sera un facteur 200, car certains des blocs nécessaires resteront en mémoire en permanence, et le nombre de comparaisons joue quand même.

Conseil pour diminuer le volume mémoire utilisé :

Utiliser des collections d'objets plutôt que des collections de pointeurs sur objets.

Comme la table est implémentée en utilisant la std::list de la STL, ce ne sera pas un gros travail de la transformer en utilisant la std::map. L'opérateur de comparaison nécessaire dans une map sera déduit de la fonction de comparaison actuelle.

Une liste de N objets est constituée de N blocs alloués séparément. Une liste de pointeurs sur objets est constituée de (2 * N) blocs.

Le temps de création de la liste sera divisé par 2. Le gain de mémoire sera au moins de (4 * N) octets. Comme la plupart des allocateurs attribuent des blocs de taille supérieure à la taille demandée, il sera probablement supérieur.

D'autre part cela simplifie en général le code. Il est de plus impossible d'oublier de libérer la mémoire.