1

我有大约 30 个 csv 文件,我正在尝试将它们并行转换为 json。转换正在发生,但需要相当长的时间。大约25分钟。每个文件将有 200 万条记录。下面是我的代码。我是 python 新手,您能否建议调整此代码的可能方法,以便加快转换时间。

import csv
import json
import os 
import multiprocessing as mp

path = '<some_path>'


""" Multiprocessing module to generate json"""

total_csv_file_list = []
for filename in os.listdir(path):
    total_csv_file_list.append(os.path.join(path,filename))

total_csv_file_list = list(filter(lambda x:x.endswith('.csv'), total_csv_file_list))
total_csv_file_list = sorted(total_csv_file_list)
print(total_csv_file_list) 


def gen_json (file_list):
        csvfile = open(file_list, 'r') 
        jsonfile = open((file_list.split('.')[0]+'.json'), 'w')
        fieldnames = ("<field_names")
        reader = list(csv.DictReader( csvfile, fieldnames))
        json.dump(reader, jsonfile,indent=4)

try:    
    p_json = mp.Pool(processes=mp.cpu_count())
    total_json_file_list = p_json.map(gen_json,total_csv_file_list)
finally:
    p_json.close()
    p_json.join()
    print("done")
4

1 回答 1

0

留在纯 python 中 - 不多,也没有必要的复杂性和获得的速度。

尝试使用比可用内核少一名的工作人员。操作系统仍然可以在免费内核上完成它的任务。因此,您的程序应该发生更少的上下文切换。

由于您对结果不感兴趣,map_async可能会比map. 您不会从此函数返回任何内容,但map返回结果仍然存在一些开销

仔细检查您是否没有达到内存限制并且操作系统没有开始交换到磁盘。不确定 DictReader 和 json 是否会将文件完全加载到内存中,或者它们是否会进行缓冲。如果交换是问题,您将需要自己进行缓冲和块写入。

继续使用纯 python,也可以尝试利用 asyncio,但它需要自定义分块和自定义生产者消费者代码以及具有多个事件循环的队列 - 每个消费者 1 个

使用 Cython 可以实现真正的速度增益。为具有明确指定的 c 类型字段的行数据定义一个类。使用纯阅读器读取 csv 并为每一行创建定义类的对象。将此类类的列表序列化为 json。这样的代码可以用 Cython 编译成 python c-extension。即使没有正确输入,Cython 编译的 python 代码也快两倍,

于 2019-12-25T01:25:57.560 回答