Un mémo lorsque j'étais impliqué dans le processus de comparaison et d'unicité de colonnes spécifiques dans une entreprise donnée. Il s'agit de supprimer plusieurs dizaines de millions de lignes d'une colonne spécifique d'un fichier avec environ 300 millions de lignes et de le sortir, et il a fallu beaucoup de temps pour l'écrire en utilisant pleinement les commandes awk et shell, mais c'est Java. Ensuite, on dit que des performances élevées pourraient être obtenues sans difficulté avec un peu d'effort.
Le code source a Gist à la fin de la page.
En conclusion, Java a été le processus le plus rapide et le plus lent que j'ai écrit, utilisant largement awk.
Comme déjà écrit, le processus exécuté lit un fichier d'environ 300 millions de lignes et supprime la duplication des première et deuxième colonnes, et le nombre total de colonnes est d'environ 20. Le tri a déjà été fait, et s'il y a des doublons, peu importe si vous gagnez en premier ou en deuxième, la condition est donc que les première et deuxième colonnes soient toujours uniques. À propos, le nombre de lignes en double est d'environ 40 millions, mais le nombre de doublons n'est pas nécessairement un, et il peut y avoir plusieurs lignes avec les mêmes première et deuxième colonnes.
Dans cette condition, le traitement unique de la commande sort et de la commande uniq ne peut pas unifier les lignes qui ont les mêmes valeurs dans les première et deuxième colonnes mais des valeurs différentes dans la nième colonne (peut être réalisé avec sort -k 1,2 -u
). Puisqu'il y a une possibilité, mais cela n'a pas été vérifié), nous avons décidé d'extraire une colonne spécifique avec awk et de vérifier la duplication en comparant la valeur de cette colonne avec la valeur précédente.
Le premier que j'ai écrit est celui qui traite if avec awk. distinct.sh
Ce processus était d'environ 120 à 150 lignes / s. À l'origine, on disait que peu importe le temps que cela prendrait, cela prendrait des dizaines de jours à cette vitesse, alors j'ai regardé la situation pendant quelques minutes et j'ai considéré l'efficacité.
En conséquence, l'utilisation de awk est limitée à l'extraction de colonne spécifique comme suit. distinct_hs.sh
Dans ce processus, le processus de comparaison et la partie d'exportation n'ont pas été effectués via awk pour accélérer le processus. En fait, c'était certainement un peu plus rapide, avec des vitesses d'environ 170-200 lignes / s.
Cependant, même s'il s'agit d'un calcul qui prend environ 20 jours, il est également possible de diviser le fichier et de gérer uniquement la duplication du début et de la fin de chaque fichier divisé séparément et de traiter en parallèle.
Cependant, compte tenu de la raison pour laquelle il est lent en premier lieu, il est facile de mettre en mémoire tampon et d'écrire le même traitement avec Java, à en juger par le jugement que les performances ne sont pas atteintes en raison des E / S détaillées. Écrire. FilePrinter.java
Le résultat est clair. La vitesse était de 185 000 à 190 000 lignes / s et le processus s'est terminé en moins de 30 minutes.
Ce qui suit montre la vitesse de chaque processus. (Je voulais juste le montrer. C'est trop écrasant pour faire un chiffre comparable.)
Les scripts shell (et awk) sont bons pour un traitement simple et petit, mais lorsqu'il s'agit d'une grande quantité de données, c'est une bonne occasion d'apprendre qu'il est nécessaire de modifier la description du traitement en conséquence ou de changer l'outil à utiliser en premier lieu. C'était une histoire qui est devenue.
Cliquez ici pour Gist: lignes distinctes avec les colonnes 1 et 2. · GitHub
Recommended Posts