J'ai un script qui doit traiter environ 20 fichiers de 100mo.
Le traitement de chaque fichier est un peu coûteux en calcul (l'I/O se fait très vite en comparaison) donc je souhaite paralléliser. Le résultat du traitement est une liste très longue de valeurs. J'ai besoin de regrouper ces listes en une seule par la suite.
La doc sur la parallélisation et les différents articles que j'ai lu m'incitent à utiliser le module de multiprocessing https://docs.python.org/2/library/multiprocessing.html
Mon problème est le suivant, les processus de traitement s’exécutent plutôt vite, mais pour renvoyer leur résultat, ce dernier doit être transmis sérialisé via pickle (ou "dill"), vu qu'il est plutôt gros, ça consomme beaucoup de temps (10 fois plus que le traitement) et de RAM (ce qui peut provoquer des crashs en production).
Il y a t'il une alternative qui me permet de tirer parti de la parallélisation sans sérialiser ? de partager directement l'objet en mémoire d'un process ?
EDIT:
Pour donner quelques chiffres (à la louche) :
En séquentiel :
- J'ai donc 20 fichiers de 100mo de texte. Je peux les parser de
manière indépendante. (taille non fixe, ça peut monter à 10Go de fichiers, mais j'ai pas mal de RAM à dispo)
- Les fichiers contiennent dans chaque ligne 3 informations qui peuvent m'intéresser, disons deux informations de clé, et plusieurs
valeur pour ce couple de clé. Il y a pas mal de parsing.
- Ça consomme environ 10s par fichier de manière naïve. Pour le moment je mets tout ça dans un dict qui contient 400k clés-valeurs
par fichier.
- Pour la suite, j'aimerais regrouper ces dictionnaires en un seul. De manière séquentielle ça coûte quasi rien.
Ça me semble du coup être un peu un problème "Map-Reduce".
Ce qui me gène avec Pickle, c'est que ça tue tout intérêt pour moi à multiprocesser. Ça introduit une étape de sérialisation (par le process fils) puis de dé-sérialisation (par le process parent) alors qu'on veut justement que chaque process dé-sérialise. On fait beaucoup plus de boulot et j'ai augmenté la charge du process principal. Accessoirement aussi ça consomme quelque chose comme 5 fois la taille des fichiers en RAM et traiter un fichier prend 10 fois plus de temps.