我上传了13万个json文件。
我使用Python
进行此操作:
import os
import json
import pandas as pd
path = "/my_path/"
filename_ending = '.json'
json_list = []
json_files = [file for file in os.listdir(f"{path}") if file.endswith(filename_ending)]
import time
start = time.time()
for jf in json_files:
with open(f"{path}/{jf}", 'r') as f:
json_data = json.load(f)
json_list.append(json_data)
end = time.time()
需要60秒。
我使用multiprocessing
进行此操作:
import os
import json
import pandas as pd
from multiprocessing import Pool
import time
path = "/my_path/"
filename_ending = '.json'
json_files = [file for file in os.listdir(f"{path}") if file.endswith(filename_ending)]
def read_data(name):
with open(f"/my_path/{name}", 'r') as f:
json_data = json.load(f)
return json_data
if __name__ == '__main__':
start = time.time()
pool = Pool(processes=os.cpu_count())
x = pool.map(read_data, json_files)
end = time.time()
需要53秒。
我使用ray
进行此操作:
import os
import json
import pandas as pd
from multiprocessing import Pool
import time
import ray
path = "/my_path/"
filename_ending = '.json'
json_files = [file for file in os.listdir(f"{path}") if file.endswith(filename_ending)]
start = time.time()
ray.shutdown()
ray.init(num_cpus=os.cpu_count()-1)
@ray.remote
def read_data(name):
with open(f"/my_path/{name}", 'r') as f:
json_data = json.load(f)
return json_data
all_data = []
for jf in json_files:
all_data.append(read_data.remote(jf))
final = ray.get(all_data)
end = time.time()
需要146秒。
我的问题是为什么ray
需要这么多时间?
是因为:
1)对于相对少量的数据,射线相对较慢?
2)我在代码中做错了吗?
3)ray
有用吗?
答案 0 :(得分:0)
我从没使用过ray,但是我很自信,我的解释应该是正确的。
原始代码执行简单的json反序列化。该代码主要需要文件IO和少量CPU。 (json反序列化相当快,这就是json是流行的交换格式的原因之一)
Ray必须将数据从一个进程推送到另一个进程(如果通过网络分布在多台计算机上)。为了做到这一点,它自己执行一些序列化/反序列化(也许它正在使用pickle和强大的TCP协议来推送参数并收集结果)。可能比实际任务需要的工作量更大。
如果您将对json数据进行更多的计算(任何需要占用更多CPU的资源),那么您将能够看到不同之处。
我的猜测是,您的示例问题太简单了,因此ray的开销超出了使用多个工作程序的好处。
换句话说。分配任务和收集结果所花费的时间/精力比执行计算结果所花费的时间/精力更多。
答案 1 :(得分:0)
我要说的是,假设1)最接近真相。 Ray似乎是一个功能强大的库,但是您要做的只是读取一堆文件。您的代码仅仅是为了进行基准测试的示例,还是更大程序的一部分?如果是后者,那么让您的基准代码反映出来可能会很有趣。
没什么大不了的,但是我对您的3个程序进行了调整,因此它们至少应该有更高的效率。
import os
import json
folder_path = "/my_path/"
filename_ending = '.json'
json_files = (os.path.join(folder_path, fp) for fp in os.listdir(f"{folder_path}") if fp.endswith(filename_ending))
def load_json_from_file(file_path):
with open(file_path, 'r') as file_1:
return json.load(file_1)
json_list = [load_json_from_file(curr_fp) for curr_fp in json_files]
import os
import json
import multiprocessing as mp
folder_path = "/my_path/"
filename_ending = '.json'
json_files = (os.path.join(folder_path, fp) for fp in os.listdir(f"{folder_path}") if fp.endswith(filename_ending))
def load_json_from_file(file_path):
with open(file_path, 'r') as file_1:
return json.load(file_1)
with mp.Pool() as pool:
json_list = pool.map(load_json_from_file, json_files)
import os
import json
import ray
folder_path = "/my_path/"
filename_ending = '.json'
@ray.remote
def load_json_from_file(file_path):
with open(file_path, 'r') as file_1:
return json.load(file_1)
json_files = (os.path.join(folder_path, fp) for fp in os.listdir(f"{folder_path}") if fp.endswith(filename_ending))
ray.init()
futures_list = [load_json_from_file.remote(curr_fp) for curr_fp in json_files]
json_list = ray.get(futures_list)
如果您有任何疑问,请告诉我。如果您可以再次运行基准测试,我很想知道有什么区别(如果有)。