Le dĂ©fi du milliard de lignes đŸ˜±

Le dĂ©fi du milliard de lignes đŸ˜±

Bienvenue dans ce nouveau projet oĂč nous allons exploiter un fichier CSV contenant un milliard de lignes. Oui, UN MILLIARD !

Il s’agit d’un dĂ©fi trĂšs amusant créé par Gunnar Morling.

Votre mission, si vous l’acceptez, est en apparence simple : Ă©crire un programme en Java pour rĂ©cupĂ©rer les valeurs de tempĂ©rature Ă  partir d’un fichier texte et calculer les tempĂ©ratures minimale, moyenne et maximale par station mĂ©tĂ©o. Il y a juste un petit dĂ©tail : le fichier contient 1 000 000 000 de lignes !

Au lieu d’utiliser un programme en Java, nous allons bien sĂ»r utiliser TypeScript, avec la librairie Simple Data Analysis (SDA) que j’ai créée (donnez-lui un ⭐). C’est une excellente occasion de tester sa puissance !

Si vous ĂȘtes bloquĂ© Ă  un moment donnĂ© dans ce projet, il peut ĂȘtre utile de revoir les leçons prĂ©cĂ©dentes expliquant les bases de SDA :

Nous utiliserons Deno et VS Code. Consultez la leçon Installation si nécessaire.

C’est parti !

Vous voulez ĂȘtre prĂ©venu quand de nouvelles leçons sont publiĂ©es ? Abonnez-vous Ă  l'infolettre ✉ et donnez une ⭐ au cours sur GitHub pour me garder motivé ! Cliquez ici pour me contacter.

Installation

Pour tout installer, utilisons setup-sda comme dans les leçons précédentes.

Créez un nouveau dossier, ouvrez-le avec VS Code et exécutez : deno -A jsr:@nshiab/setup-sda

Ensuite, lancez deno task sda pour surveiller main.ts et ses dépendances.

Une capture d'écran de VS Code aprÚs avoir exécuté setup-sda.

💡

Pour que SDA fonctionne correctement, il est prĂ©fĂ©rable d’avoir au moins la version 2.1.9 de Deno. Pour vĂ©rifier votre version, vous pouvez exĂ©cuter deno --version dans votre terminal. Pour la mettre Ă  jour, exĂ©cutez simplement deno upgrade.

Les données

Dans le dĂ©fi original, vous devez copier un rĂ©pertoire GitHub et exĂ©cuter un script pour gĂ©nĂ©rer un fichier CSV contenant 1 milliard de lignes. Mais je l’ai fait pour vous et j’ai tĂ©lĂ©versĂ© le fichier compressĂ© sur mon Google Drive.

Téléchargez les données ici. Cela peut prendre quelques minutes car le fichier fait environ 4 Go.

Ensuite, placez-le dans votre dossier data et décompressez-le. La version décompressée du fichier CSV fait environ 13 Go.

Pour charger les données, copiez et collez ce code dans votre main.ts. Selon votre ordinateur, cela peut prendre de quelques secondes à quelques minutes.

main.ts
import { SimpleDB } from "@nshiab/simple-data-analysis";
 
const sdb = new SimpleDB({ logDuration: true });
 
const table = sdb.newTable();
 
await table.loadData("sda/data/measurements.csv");
await table.logTable();
 
await sdb.done();

Une capture d'écran de VS Code aprÚs avoir chargé un milliard de lignes de données.

FĂ©licitations ! Vous venez de charger 1 000 000 000 de lignes de donnĂ©es ! Sur mon MacBook Pro M1 avec 16 Go de RAM, cela a pris environ 26 secondes. đŸ„ł

Selon la RAM disponible sur votre ordinateur, vous pourriez voir un dossier .tmp apparaßtre dans votre projet. Si les données sont plus volumineuses que votre RAM, ce dossier sera utilisé pour traiter toutes les données en stockant des morceaux prétraités.

Ce dossier .tmp peut devenir assez volumineux. Sur mon ordinateur, aprÚs la premiÚre exécution, il fait environ 8 Go.

💡

Si vous voulez nettoyer votre cache, exĂ©cutez deno task clean. Cela supprimera .tmp. Vous pouvez aussi le supprimer manuellement, mais n’oubliez pas de vider votre corbeille.

Le défi

Comme vous pouvez le voir ci-dessus, les données sont simplement une liste de villes avec des températures.

Maintenant, le dĂ©fi est de calculer les tempĂ©ratures minimale, moyenne et maximale par ville. Les rĂ©sultats doivent Ă©galement ĂȘtre triĂ©s par ordre alphabĂ©tique des villes.

Le code est trĂšs simple avec SDA. Vous n’avez mĂȘme pas besoin de trier les lignes manuellement, car summarize le fait par dĂ©faut.

main.ts
import { SimpleDB } from "@nshiab/simple-data-analysis";
 
const sdb = new SimpleDB({ logDuration: true });
 
const table = sdb.newTable();
await table.loadData("sda/data/measurements.csv");
await table.summarize({
  values: "temp",
  categories: "city",
  summaries: ["min", "mean", "max"],
});
await table.logTable();
 
await sdb.done();

Une capture d'écran de VS Code aprÚs avoir agrégé un milliard de lignes de données.

Le chargement et l’agrĂ©gation du milliard de valeurs a pris moins de 50 secondes sur mon ordinateur avec SDA ! 🚀

Accélérer les choses

Lorsque vous utilisez des méthodes comme loadData et summarize, SDA effectue diverses vérifications pour garder les méthodes faciles à utiliser et éviter les erreurs potentielles.

Cependant, lorsque vous travaillez avec un fichier aussi volumineux, ces vérifications peuvent prendre pas mal de temps


Si vous connaissez SQL, vous pouvez Ă©crire et exĂ©cuter vos propres requĂȘtes pour faire exactement ce que vous voulez, sans aucun extras !

Voici comment exĂ©cuter une requĂȘte SQL qui relĂšve le dĂ©fi. Notez que j’utilise LIMIT 10 pour ne retourner que les 10 premiĂšres lignes du rĂ©sultat, mais tous les calculs sont effectuĂ©s.

main.ts
import { SimpleDB } from "@nshiab/simple-data-analysis";
 
const sdb = new SimpleDB({ logDuration: true });
 
const result = await sdb.customQuery(`
SELECT city,
    MIN(temp) AS min_temp,
    ROUND(MEAN(temp), 1) AS mean_temp,
    MAX(temp) as max_temp
FROM read_csv('sda/data/measurements.csv')
GROUP BY city
ORDER BY city
LIMIT 10;
`,
  { returnDataFrom: "query" },
);
 
console.table(result);
 
await sdb.done();

Une capture d'écran de VS Code aprÚs avoir agrégé un milliard de lignes de données.

Et cela s’exĂ©cute en seulement
 16 secondes ! đŸ’„đŸ’„đŸ’„

Mais
 comment ?

Bien que SDA soit une librairie TypeScript, sous le capot, elle utilise DuckDB, un systÚme de base de données ultra-rapide écrit en C++.

Lorsque vous utilisez des mĂ©thodes comme loadData ou summarize, SDA traduit tout en SQL et demande Ă  DuckDB de l’exĂ©cuter.

D’aprĂšs mon expĂ©rience, utiliser SDA est plus rapide que d’utiliser Python avec Pandas ou R avec le Tidyverse.

Pour tester et comparer les performances de la librairie, j’ai calculĂ© la tempĂ©rature moyenne par dĂ©cennie et par ville en utilisant les tempĂ©ratures quotidiennes des donnĂ©es climatiques ajustĂ©es et homogĂ©nĂ©isĂ©es du Canada, soit environ 1,7 Go avec 22 millions de lignes de donnĂ©es. Pour plus de dĂ©tails, consultez le rĂ©pertoire GitHub de la librairie.

J’ai exĂ©cutĂ© les mĂȘmes calculs avec simple-data-analysis@4.0.1 (Node.js, Bun et Deno), Pandas (Python) et le tidyverse (R).

GrĂące Ă  DuckDB, Simple Data Analysis a Ă©tĂ© l’option la plus rapide.

Un graphique montrant la durée de traitement de plusieurs scripts dans différents langages

Cependant, rien ne vous empĂȘche d’utiliser DuckDB avec Python et R. Mais vous n’aurez pas toutes les mĂ©thodes faciles Ă  utiliser et les exemples que j’ai Ă©crits pour SDA. 😬

J’ai Ă©galement testĂ© les calculs gĂ©ospatiaux, qui sont encore en plein dĂ©veloppement avec DuckDB. Python et R restent les plus rapides pour le moment ! Encore une fois, pour plus de dĂ©tails, consultez le rĂ©pertoire.

Conclusion

Voilà, c’est tout ! J’espùre que ce projet vous a convaincu de la performance de la librairie Simple Data Analysis.

Plus rien ne vous empĂȘche d’analyser des ensembles de donnĂ©es massifs avec TypeScript maintenant ! 💃đŸ•ș

Vous avez aimé ? Vous voulez ĂȘtre prĂ©venu quand de nouvelles leçons sont publiĂ©es ? Abonnez-vous Ă  l'infolettre ✉ et donnez une ⭐ au cours sur GitHub pour me garder motivé ! Contactez-moi si vous avez des questions.