Après avoir lu un article sur l'utilisation du logiciel Sysprof à des fins d'optimisation, j'ai
voulu tester ce logiciel par moi même.
Sysprof est un outil linux qui donne des informations assez précises sur la consommation
en ressources de l'ensemble du système. Pour tester un logiciel, il suffit de lancer l'analyse
Sysprof, commander une tâche lourde au logiciel puis d'étudier les résultats de l'analyse à la
recherche de problèmes de performances.
J'ai utilisé un logiciel de Data Mining nommé KnowkedgeDiscovery. Le logiciel est codé en C++ avec le toolkit Qt. Il a été conçu dans le but de travailler sur
de grande quantité de données et d'être efficace. C'est donc un bon
candidat pour une session d'optimisation.
Les informations que fourni Sysprof sont éloquentes : Le logiciel passe la plupart de son temps
dans 3 fonctions qui sont en fait des getters :
On peut voir dans le tableau de gauche que les getters getValue, getClassValue, getClassCol prennent
respectivement 30, 17, et 18 pourcents de l'utilisation des ressources du système.
Cela veut dire qu'une grande partie du temps processeur est utilisé pour accéder aux informations
via ces getters. J'ai trouvé deux moyens simple de les améliorer :
- Mettre les fonctions getters inline (l'appel de la fonction est remplacé par le code de la fonction, on économise le coût de l'appel mais on fait grossir le code) ;
- Simplifier au maximum les getters.
En temps normal les petites fonctions comme les getters sont automatiquement mises inline
au moment de la compilation mais en ce qui concerne mon logiciel il semble que GCC
décide de ne pas le faire.
Pour indiquer explicitement au compilateur qu'une fonction doit être mise inline il faut
déplacer l'implémentation de la fonction dans le même fichier que la définition de la classe et
ajouter le mot clé inline devant la définition de la fonction.
Par exemple en travaillant sur la fonction getValue(...) dans
KdTableData.cpp :
float KdTableData::getValue(int row, int col)
{
if( col==classCol )
qWarning("getValue called with col==classCol");
return table[row]->col[col];
}
Est devenu dans le fichier KdTableData.h :
inline float KdTableData::getValue(int row, int col)
{
return table[row]->col[col];
}
En effectuant ces deux modifications simples avec les trois fonctions nommées
précédemment j'ai multiplié les performances d'analyse de mon logiciel par
un facteur clairement supérieur à 3.
Ce petit travail montre une chose importante : Même si l'on se croit capable de deviner à l'avance
quelles seront les goulets d'étranglement du logiciel, il est plus efficace d'écrire rapidemment
et proprement le code. Les optimisations se font à la fin, en utilisant sur des outils des tests.
Sysprof, un "profiler" puissant pour Linux.