Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Grosse liste: comment optimiser

+6 votes

Dans mon programme, je télécharge des articles sur le net en masse. Les articles en question ont chacun un DOI, une sorte d'id unique (c'est une string). Ce n'est pas moi qui le définis, il vient avec l'article. Une fois l'article dl, j'en extrais certaines informations, que je mets en base de donnée (sqlite).

Quand je relance le programme, je récupère le DOI pour chaque article, et si le DOI est déjà en base de donnée, je ne retélécharge pas l'article, et je ne refais pas les traitements.

Seulement voilà, pour vérifier que le DOI n'est pas déjà en base de donnée, je fais ça: au début du programme, je fais une seule requête SQL, et je construis une liste avec tous les DOI déjà présents en bdd. Une grosse liste. J'ai plus de 20000 items dans ma bdd, donc ça fait une liste de plus de 20000 éléments.
De plus, je construis une liste de booléens, de même taille que la liste des DOI, pour faire d'autres vérifications.

J'ai benchmarké mon programme avec memory_profiler, qui me dit que cette liste + la liste de booléens prend environ 500 Mo en RAM. C'est beaucoup, beaucoup trop. Je dois trouver quelque chose de plus économe.

Donc ma question, qu'est ce qu'il vaut mieux faire:
- construire les 2 grosses listes comme je fais, et sacrifier 500 Mo de mémoire, et à chaque DOI, vérifier si la liste le contient
- faire une requête SQL à chaque fois que je veux vérifier le DOI

Voilà, j'aurais besoin de vos avis, je voudrais connaître les avantages et les inconvénients des 2 méthodes.

demandé 28-Mar-2015 par Rififi (508 points)
reclassée 28-Mar-2015 par Rififi

1 Réponse

+5 votes
 
Meilleure réponse

Instinctivement, je dirai que faire une grosse requête pour récupérer tout les ID des articles n'est pas forcément le plus efficace si la base de données grossit régulièrement en taille.

Petite question : je ne comprends pas bien le sens de cette phrase :

Quand je relance le programme, je récupère le DOI pour chaque article,
et si le DOI est déjà en base de donnée, je ne retélécharge pas
l'article, et je ne refais pas les traitements.

Tu récupère le DOI à quel endroit ?

Sinon, au doigt mouillé, comme ça, pourquoi ne pas faire la vérification par lots, par exemple en scindant ta requête initiale en petite requêtes retournant chacune 100 éléments, en vérifiant ces 100 éléments, puis en passant au 100 suivants ? De cette façon, tu occupera toujours la même place en mémoire, même si ta vérification initiale prendra plus de temps.

En termes de code, ça doit être implémentable en utilisant les générateurs.

répondu 28-Mar-2015 par eliotberriot (678 points)
sélectionné 28-Mar-2015 par Rififi

En fait les articles proviennent de plusieurs sites. Chaque site propose sa page de flux rss. Donc je fais une requête http par site pour avoir la page de flux rss, qui me donne elle même une centaine de DOI.

Mais merci à toi en fait, tu m'as donné la solution (à peu près). Maintenant je fais une plus petite liste, contenant les DOI des articles, par site.

En bref je traite les articles site par site et je n'ai plus besoin de construire une méga liste. Merci.

Content que tu aies trouvé une solution !

...