Optimisations
Constant folding
Motivation
Les modèles de calculs écrits en Publicodes sont par design implémentés pour être le plus transparent et intelligible possible pour le plus grand nombre. Cela implique de détailler au maximum les calculs, ce qui peut conduire à une complexité importante des modèles. Cependant, cette complexité n’est justifiée que pour la documentation et non pour le calcul en lui-même.
Par exemple, considérons les règles suivantes :
alimentation . déchets . gestes . bonus compostage biodéchets:
formule:
somme:
- omr . putrescibles . réduction compost
- (-1) * omr . putrescibles . compostés
unité: kgCO2e
alimentation . déchets . omr . putrescibles . réduction compost:
formule: omr . putrescibles * (gisement réduction / quantité réelle)
unité: kgCO2e
La règle alimentation . déchets . omr . putrescibles . réduction compost
dépends de 18 autres règles pour être calculée. Cependant, la valeur ne dépend
pas de l’utilisateur·ice et pourrait être calculée à l’avance (c’est une constante).
C’est l’objectif de l’optimisation par constant
folding : calculer toutes les
valeurs qui ne dépendent pas de l’utilisateur à l’avance et remplacer les règles
directement par leur valeur.
Ainsi, après optimisation on obtient :
alimentation . déchets . gestes . bonus compostage biodéchets:
formule:
somme:
- 11.505999999999998
- (-0.4949999999999999)
Usage
L’optimisation par constant folding est disponible dans le module @publicodes/tools/optims
via la fonction constantFolding
qui prend en paramètre :
- un moteur Publicodes (instancié avec le jeu de règles à optimiser)
- un prédicat qui prend en paramètre un couple
(nom de la règle, noeud de la règle)
et retournetrue
si la règle doit être conservée après optimisation - un objet de paramètres :
isFoldedAttr
: le nom de l’attribut à utiliser pour marquer une règle comme optimisée (par défautoptimized
)
Exemple
import Engine from 'publicodes';
import { constantFolding } from '@publicodes/tools/optims';
const optimizedRules = constantFolding(
// A publicode engine instantiated with the rules to optimize.
new Engine(baseRules),
{
// A predicate returning true if the rule needs to be kept.
toKeep: (rule) => {
return ['root', 'root . bis'].includes(rule.dottedName) || !!rule.rawNode['to keep'];
}
}
);