Leader français des logiciels de gestion et expert en infrastructure réseaux

 Accueil >  Services >   Support 
Menu des thèmes

Lettres d'information

Actualités

Des calculs de bulletins (beaucoup) plus rapides
Note créée le 26/3/2019, dernière modification le 18/4/2019

Courant mars-avril 2019, nous avons mené un gros travail d'optimisation sur le programme de calcul des bulletins. Tout cela est détaillé dans la note ci-dessous.
A la clé, on observe un temps moyen de calcul d'un bulletin divisé à minima par 2,5.

A cela s'ajoute une optimisation possible dans la configuration du serveur de données HFSQL, pour les plus grosses configurations où les données de LDPaye sont gérées en HFSQL Client-Serveur (et non en HFSQL Classic comme c'est le cas le plus souvent). PCSoft, l'éditeur de la base de données HFSQL, a en effet dévoilé récemment, sur son blog de support technique, une note relative aux performances des serveurs HFSQL. Elle indique qu'il peut être pertinent, dans certaines configurations de serveurs Windows, de désactiver le mécanisme d'équilibrage de charge intégré au serveur HFSQL. Nous l'avons testé dans une entreprise utilisant LDPaye avec de très gros volumes de données : le résultat est sans appel. Le temps moyen de réponse du serveur HFSQL a été là-aussi divisé par deux !

Ces deux optimisations s'additionnant, on peut dans certains cas diviser le temps de calcul par 4 ! Non négligeable compte-tenu que la paye a ceci de particulier que tout le monde souhaite calculer ses bulletins quasiment au même moment. La charge des serveurs est donc très forte sur une période de temps assez brève : un ou deux jours dans le mois.  Avec un temps de calcul en dessous de 2 secondes, on peut désormais calculer plus de 1000 bulletins à l'heure.


Principales améliorations apportées au moteur de calcul des bulletins

Notion de contexte global
De façon générale, à de nombreux endroits dans le calcul du bulletin, on a remplacé des accès « directs » aux fichiers du plan de paye (rubriques, cotisations, types de cumuls, liens entre rubriques et cotisations, entre rubriques et cumuls...) par des accès au travers de requêtes SQL. L'avantage des requêtes est qu'elles ne sont transmises et exécutées par le serveur HFSQL qu'une seule fois en début de calcul du bulletin. Par la suite, tous les accès à ces requêtes réalisés durant le calcul d'un bulletin ne génèrent aucun trafic réseau et aucune charge supplémentaire du serveur HFSQL. Tout se fait en local sur le poste de travail, où les requêtes (et donc les données correspondantes) sont conservées en mémoire.
Dans ce qui suit, on parlera de « contexte global » : cette expression désigne l'ensemble des données issues du plan de paye qui sont mises en mémoire au travers de ces requêtes.
Précisons qu'il s'agit uniquement des données du plan de paye qui ne sont pas propres à un salarié en particulier. Ce sont essentiellement les données correspondant au paramétrage des rubriques, cotisations, types de cumuls, contrats de prévoyance.

Dans la foulée, une autre optimisation évidente a été faite quand on lance un ensemble de calculs via le bouton Tout calculer : plutôt que de charger le contexte global au début de chaque calcul d'un bulletin, on ne le fait qu'une seule fois au premier bulletin calculé. Ainsi, si on a lancé le calcul pour une centaine de salariés, le contexte global n'est lu qu'une seule fois, puis réutilisé pour chacun des 100 bulletins calculés.

Mode optimisé
Pour aller plus loin encore, on peut basculer dans le Mode optimisé. Dans ce mode, même sans passer par le bouton Tout calculer, le contexte global n'est pas relu. Ainsi, si on calcule ou recalcule un à un les bulletins des différents salariés, le contexte global n'est lu qu'au premier calcul de bulletin (depuis que la fenêtre de calcul des bulletins a été ouverte ou depuis que l'on est entré en mode optimisé).
Ce mode optimisé n'est pas activé par défaut. Si vous souhaitez le mettre en œuvre, il faut le demander expressément dans la fenêtre Paramètres généraux, sur l'onglet Préférences utilisateur.  On y trouve une préférence « globale » pour ce mode optimisé, avec 3 valeurs possibles :  Non proposé, Inactif et Actif. Et si vous choisissez une option autre que Non proposé, vous pouvez éventuellement décliner cette préférence pour chaque utilisateur.

Remarque très importante : en mode optimisé, toute modification faite en parallèle sur le plan de paye (que ce soit depuis un autre poste de travail, depuis une autre session de LDPaye ouverte sur le même poste de travail ou même depuis la session courante de LDPaye), toute modification donc ne sera pas prise en compte, et ce tant que l'on ne sort pas du mode optimisé (en cliquant sur le bouton Mode optimisé présent en haut à droite de la fenêtre principale de calcul des bulletins) ou que l'on ne referme pas la fenêtre principale de calcul des bulletins. 
Disons-le clairement : il ne faut pas modifier le plan de paye quand on travaille en mode optimisé. Les bulletins qui en résulteraient seraient très probablement incohérents, le système ayant tenu compte d'une partie des modifications opérée sur le plan de paye, celles n'étant pas chargées dans le contexte global.
Ce mode doit donc être écarté dans les phases de démarrage de LDPaye (quand on adapte le plan de paye) ainsi que dans toutes les phases où l'on apporte des modifications au plan de paye (en début d'année par exemple). En revanche, en fonctionnement courant, essentiellement sur les configurations à fort volume (disons plus de 300 bulletins mensuels), il permet un léger gain de performance et surtout une moindre charge du réseau et du serveur HFSQL. 
Pour éviter dans la mesure du possible des erreurs de manipulation, dès lors que la fenêtre de calcul des bulletins est ouverte et que le mode optimisé est actif, l'accès en création/modification/suppression aux fiches rubriques, cotisations, types de cumuls, contrats de prévoyances, paramètres DSN est bloqué dans la session courate de LDPaye (boutons grisés), et ce jusqu'à ce que l'on sorte du mode optimisé ou que l'on ferme la fenêtre principale de calcul des bulletins.

Nouveau mode de gestion des éléments automatiques

Le calcul d'un bulletin de paye se fait à partir des éléments variables d'une part (que ce soit les éléments saisis, les éléments fixes ou les éléments interfacés), des éléments automatiques d'autre part (le salaire de base, le total brut, les cotisations...).
Jusqu'alors, à chaque calcul de bulletin, le programme commençait par ajouter dans le fichier des éléments variables tous les éléments automatiques découlant du profil rubriques et du profil cotisations du salarié concerné, en prenant soin en cas de recalcul de commencer par supprimer ceux résultant du calcul précédent. Dans la plupart des cas, le nombre d'éléments automatiques est bien supérieur au nombre d'éléments saisis ou interfacés ; on voit parfois des bulletins composés de 300 éléments automatiques ! Multipliez cela par le nombre de salariés et par 36 ou 48 mois et l'on obtient un fichier de plusieurs millions d'enregistrements. Or, le temps de mise à jour d'un fichier est fortement corrélé à la taille du fichier.
Une optimisation assez radicale a donc été faite : les éléments automatiques ne sont plus inscrits dans le fichier des éléments variables. Le moteur de calcul opère désormais via un tableau d'enregistrements stocké dans la mémoire locale du poste de travail. Ce tableau est alimenté d'une part par les éléments variables préexistants (ceux ayant été saisis, ou qui sont fixes, ou qui ont été interfacés), d'autre part par les éléments automatiques. Une fois ce tableau constitué, le moteur le trie par N° de rubrique/cotisation, puis calcule ces éléments un à un pour en déduire les lignes du bulletin. Et c'est uniquement à ce moment-là qu'il ajoute certains éléments automatiques dans le fichier des éléments variables, quand c'est indispensable : pour enregistrer une période associée à la ligne de bulletin (les dates début-fin sont présentes dans le fichier des éléments variables, mais pas dans le fichier des lignes de bulletin) ou parce qu'on a un commentaire associé à la ligne de bulletin (un commentaire ne peut être associé à une ligne de bulletin que par l'entremise d'un élément variable). Finalement, pour un bulletin, au lieu d'écrire plusieurs centaines d'éléments automatiques dans le fichier des éléments variables, on n'en écrira que 4 ou 5. D'où une taille de fichier diminuée d'un facteur 30 à 100 !  Rien que cette optimisation a pour effet de diviser le temps de calcul d'un bulletin par un facteur 2 à minima.
Remarque : en tenant la touche Majuscule enfoncée lors d'un calcul de bulletin (ou lors du lancement d'un Tout calculer), le calcul est opéré comme auparavant, avec génération dans le fichier des éléments variables de tous les éléments automatiques. Intérêt : pouvoir ensuite modifier ou supprimer, via la saisie des éléments variables, un élément automatique. Rappelons en effet que l'on avait accès à ces éléments automatiques depuis la saisie des éléments variables, même s'ils étaient masqués par défaut. Il fallait choisir l'option Afficher tous les éléments automatiques en haut à droite de la fenêtre de saisie. Désormais, vous ne voyez plus ces éléments automatiques puisqu'ils ne sont pas inscrits dans le fichier. Vous n'y trouverez qu'une toute petite partie d'entre eux, ceux liées à une période ou à un commentaire sur le bulletin. Si vous souhaitez modifier ou supprimer un élément qui n'apparait plus ici (même si ce n'est certainement pas la meilleure méthode dans l'absolu, cela peut dépanner pour régler rapidement un cas particulier), il vous faut recalculer le bulletin en tenant la touche Majuscule enfoncée. Vous retrouverez alors tous les éléments automatiques mis en jeu dans le bulletin, exactement comme auparavant. Une fois l'élément automatique modifié ou supprimé, vous pouvez recalculer le bulletin, cette fois sans qu'il soit nécessaire de tenir la touche Majuscule enfoncée : en effet, tout élément automatique ayant été marqué comme modifié ou supprimé est conservé dans le fichier au travers d'un recalcul, au même titre qu'une élément variable saisi.

Autres optimisations

  • Dans la première phase de calcul d'un bulletin, celle qui consiste à générer les éléments automatiques d'un bulletin venant en complément des éléments variables saisis, fixes ou interfacés, on ne génère plus les éléments automatiques qui sont conditionnés, si la condition n'est pas vérifiée. Sauf pour les conditions portant sur la valeur d'un cumul ou faisant appel à une fonction personnalisée : pour ces deux cas, c'est dans la deuxième phase de calcul du bulletin que la condition sera évaluée et que l'élément automatique sera éventuellement écarté, comme auparavant. On élimine ainsi de très nombreux éléments automatiques dès qu'on le peut. Cela est le cas par exemple quand on a des rubriques ou cotisations qui sont conditionnées par un code société ou établissement, ou encore par la valeur d'une constante générale comme l'effectif. 
    Cela est mis en œuvre également pour les cotisations prévoyance, où la condition d'affiliation du salarié au contrat auquel est associée chaque cotisation prévoyance est vérifiée dès cette phase 1, donc beaucoup plus tôt, évitant ainsi pas mal de travail superflu au moteur de calcul.

  • Au sein du programme de calcul, l'ajout des éléments dits « automatiques » a été standardisé dans une procédure nommée xAjouterUnElémentVariableAuto(NuméroRubrique, Libelle , Nombre, Taux, Montant [, DateDebut, DateFin]).
    Prenons un exemple pour fixer les choses : imaginons qu'on ait à faire une savante répartition d'un total d'heures pour distinguer des heures normales, des heures supplémentaires, des heures à récupérer... Auparavant, on faisait appel à une fonction personnalisée qui mettait à jour un certain nombre de cumuls. Et on avait en parallèle tout un jeu de rubriques paramétrées en éléments automatiques, rubriques qui récupéraient leurs valeurs en entrée dans les cumuls mis à jour par la fonction personnalisée. Si la fonction personnalisée avait calculé des valeurs nulles pour tout ou partie des cumuls, les éléments automatiques alimentés par ces cumuls étaient écartés dans la 2ème phase de calcul du bulletin. L'inconvénient de cette façon de faire est qu'elle fait appel à de nombreux cumuls et de nombreux éléments automatiques. Assez moyen pour les performances.
    A l'avenir, on pourra se passer des cumuls intermédiaires qui n'avaient pour objet que d'alimenter les éléments automatiques visés par l'élément d'origine : c'est dans la fonction personnalisée mise en œuvre par l'élément d'origine qu'on créera directement, si nécessaire, les éléments qui découlent de l'élément d'origine, avec directement les bonnes valeurs dans les colonnes Nombre, Taux et/ou Montant. Et ces éléments qui découlent de l'élément d'origine feront référence à des rubriques qui ne seront plus paramétrées en élément automatique, donc plus générées systématiquement, mais seulement à bon escient.
    L'intérêt est que cette procédure peut désormais facilement être appelée depuis une fonction personnalisée. Grâce à cela, un élément variable, qu'il soit saisi ou automatique, peut déclencher l'ajout d'autres éléments automatiques lors du calcul, au travers d'une fonction personnalisée. On peut ainsi éviter la génération de nombreux éléments automatiques qui n'ont de sens qu'en présence d'un autre élément sur le même bulletin.

  • Le programme de calcul des bulletins ne crée plus les cumuls cotisations qui sont entièrement nuls (pas de brut soumis, pas de base, pas de plancher ni plafond, pas de montant de cotisation salariale ni patronale). On diminue ainsi le volume du fichier des cumuls cotisations, et par là-même le temps de mise à jour de ce fichier à chaque calcul. Cela concerne par exemple des cotisations comme le forfait social 16% ou 20%, que l'on calcule bien souvent systématiquement, alors qu'il n'y a pas de brut soumis la plupart du temps.







 

\n