1
votes

Convertir une fonction simple en une fonction multithread

J'ai la fonction suivante que j'aimerais transformer en une fonction multi-thread:

{"dateadded": "2019-11-04 12:33:27", "url_status": "online", "tags": "elf", "url": "http://2.56.8.16/bins/arm7", "reporter": "Gandylyan1", "threat": "malware_download", "id": "251402"}
{"dateadded": "2019-11-04 12:33:25", "url_status": "online", "tags": "elf", "url": "http://2.56.8.16/bins/arm6", "reporter": "Gandylyan1", "threat": "malware_download", "id": "251401"}

En gros, elle va chercher dans un fichier JSON pour une valeur. Le problème principal est que le fichier est volumineux (plus de 50 Mo) et j'ai besoin de résultats le plus rapidement possible (plus de 7 secondes sont considérés comme trop).

Ceci est un extrait du fichier pour que vous puissiez voir la structure:

from __future__ import print_function
import os
import json


def url_searcher(value):
    url_file_path = "C:\\Users\\Link\\Desktop\\"

    for filename in os.listdir(url_file_path):
        if filename == "url_list.json":
            with open(url_file_path + filename) as f:
                for line in f:
                    returnJson = json.loads(line)
                    if value in returnJson["url"]:
                        return returnJson


print(url_searcher("http://zadkay.com/blog/wwp/51065983.jpg"))

Question:

Quelles sont les étapes? Est-ce une bonne idée et cela améliorera-t-il la vitesse d'obtention d'un résultat?

Ici, vous pouvez voir un exemple JSON du fichier avec plus de lignes: https://pastebin.com/MXYTg1CV

Merci


7 commentaires

peut-être devriez-vous travailler avec du texte sans convertir de JSON en structure Python. Si l'URL est toujours au même endroit, vous pouvez la découper et vérifier si la valeur se trouve dans cette partie du texte.


peut-être que cela fonctionnera plus rapidement si vous utilisez simplement if value in line:


Je dois utiliser JSON car la même fonction s'appliquera à une structure différente. Key, Value est ce dont j'ai besoin ici, également à cause du retour qui doit être un json.


vous pouvez convertir une chaîne JSON en dictionnaire après avoir trouvé la valeur dans le texte


ok, mais qu'en est-il du multi-threading? est une bonne idée avec le code actuel?


pouvez-vous d'abord transformer les données en une structure de données plus appropriée? par exemple. un dictionnaire saisi par l ' url , ou une base de données avec un index approprié


Python a besoin d'un certain temps pour créer un thread , et les threads peuvent ne pas fonctionner en même temps en Python. Peut-être que multiprocessing.Pool fonctionnerait mieux. Vous devriez donc essayer de voir si cela vous aide.


3 Réponses :


0
votes

Créer un thread en python est vraiment simple

import threading

thread_one= threading.Thread(name='searcher', target=url_searcher, args=(value))                
thread_one.start()

https://docs.python.org/3/library/threading.html

Mais je pense que cela ne réduira pas le temps de traitement, cela ne vous permettra que de lire plusieurs fichiers à la fois et peut même prendre plus de temps pour traiter chaque fichier.

La structure du fichier est toujours la même? Avez-vous essayé de le traiter sous forme de fichier texte brut et de rechercher le nom de la clé?


0 commentaires

0
votes

Ressemble à peu près à une opération limitée d'E / S:

from multiprocessing.dummy import Pool
from __future__ import print_function
from functools import partial
import json
import glob


def url_searcher(pathlist, value):

    for filename in pathlist:

         with open(filename) as f:

            for line in f:

                returnJson = json.loads(line)

                if value in returnJson["url"]:

                    return returnJson

no_of_threads = 4 #can be set manually or allocated automatically by Pool (see docs)

url_file_path = "C:\\Users\\Link\\Desktop\\"
value = "very_important_stuff" #adjust to your liking!

workers = Pool(no_of_threads)

pathlist = [f for f in glob.iglob(url_file_path, recursive=recurse) if "url_list.json" in f]

result = workers.map(partial(url_searcher, value = value), pathlist)

workers.close()       
workers.join()


0 commentaires

2
votes

Premièrement, mesurez, pas devinez. Familiarisez-vous avec snakeviz: https://jiffyclub.github.io/snakeviz/

with open(url_file_path + filename) as f:
    for line in f:
        # returnJson = json.loads(line)
        # if value in returnJson["url"]:
        #     return returnJson
        if value in line:
            returnJson = json.loads(line)
            return returnJson

Sur ma machine, 65% du temps est passé à la fonction décoder de decoder.py de la bibliothèque json.

Essayons une amélioration simple:

pip install snakeviz
python -m cProfile -o program.prof my_program.py
snakeviz program.prof

Sur ma machine, je vois une amélioration de 10 fois le temps d'exécution.


0 commentaires