es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Acelere la conversión de json con pypy3.

¿Hay alguna forma de acelerar la conversión de flujos de cadenas a json/diccionario usando pypy3? Sé que ujson en python3 podría ser más rápido que json de python3, pero no es realmente más rápido que json.loads() de pypy3.

Más información sobre lo que tengo, tengo un programa leyendo flujos de cadenas json desde un subproceso y convirtiéndolos (cargándolos) mediante json.loads(). Si comento la línea de ejecución de carga de json (básicamente solo leyendo el stdout del subproceso), tarda aproximadamente el 60% del tiempo total de ejecución.

Así que estaba pensando que usar un grupo de procesos o hilos podría mejorar la velocidad (quizás hasta un 80% del tiempo de ejecución) y realizar la conversión en paralelo. Desafortunadamente, no hizo nada. Usar multiprocesos dio los mismos resultados, y el multihilo tardó más que un solo proceso (probablemente debido principalmente a la sobrecarga y serialización). ¿Hay algún otro cambio que pueda mejorar el rendimiento con pypy3?

Para referencia, aquí hay un ejemplo rápido de código (solo leyendo desde algún archivo en su lugar):

import json
import timeit
from multiprocessing.pool import ThreadPool
from multiprocessing import Pool


def get_stdout():
    with open("input.txt", "r") as f:
        for line in f:
            yield line


def convert(line):
    d = json.loads(line)
    return d


def multi_thread():
    mt_pool = ThreadPool(3)
    for dict in mt_pool.imap(convert, get_stdout()):
        pass


def multi_process():
    with Pool(3) as mp_pool:
        for dict in mp_pool.imap(convert, get_stdout()):
            pass


def regular():
    for line in get_stdout():
        d = convert(line)


print("regular: ", timeit.repeat("regular()", setup="from __main__ import regular", number=1, repeat=5))
print("multi_thread: ", timeit.repeat("multi_thread()", setup="from __main__ import multi_thread", number=1, repeat=5))
print("multi_process: ", timeit.repeat("multi_process()", setup="from __main__ import multi_process", number=1, repeat=5))

Resultado:

regular: [5.191860154001915, 5.045155504994909, 4.980729935996351, 5.253822096994554, 5.9532385260026786]
multi_thread: [5.08890142099699, 5.088432839998859, 5.156651658995543, 5.781010364997201, 5.082046301999071]
multi_process: [26.595598744999734, 30.841693959999247, 29.383782051001617, 27.83700947300531, 21.377069750000373]
Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Parece que el uso de multiprocessing o multithreading no mejora el rendimiento de la conversión de flujos de cadenas a JSON/diccionario mediante pypy3. Podría valer la pena buscar en otras bibliotecas como ujson, que es más rápido que la biblioteca json de Python. Además, podría intentar usar Cython para compilar su código y ver si mejora el rendimiento.

Comments are closed.