需要进行大量的复杂运算,为了提高效率,使用了多进程,但是使用多进程后效率并未提升
import igrf_utils as iut #计算函数
import io_options as ioo #计算函数
import math
import datetime
import win32api,win32con
import pandas as pd
from math import sin as sin
from math import cos as cos
from math import pi as pi
from scipy import interpolate
import tqdm
def earth_mag(#--省略--): #计算函数1
#省略
return eff
def xy_bl(#-省略): #计算函数2
#省略
return(B,L)
from multiprocessing.dummy import Process
coo_file2 = './.det'
start_time = datetime.datetime.now()
xyz_dat = open(coo_file2,'r').readlines()
data_nums = len(xyz_dat)
line_list = []
def earth_cal1(xyz_dat,line_list): #逻辑函数
for n in tqdm.tqdm(range(len(xyz_dat):
point = int(xyz_dat[n].split(',')[0])
x = round(float(xyz_dat[n].split(',')[1]),3)
y = round(float(xyz_dat[n].split(',')[2]),3)
z = round(float(xyz_dat[n].split(',')[3]),3)
LTD = xy_bl(x,y,a,f,L0)[0]
LND = xy_bl(x,y,a,f,L0)[1]
alt = z/1000
eff = earth_mag(LTD,LND,alt,year,igrf)
new_line_list =[point,x,y,z,eff]
line_list.append(new_line_list)
process_nums = 4
nums = data_nums//process_nums
xyz_data_list= []
li_child_porc = []
for i in range(process_nums-1):
xyz_data_list.append(xyz_dat[inums : (i+1)*nums])
xyz_data_list.append(xyz_dat[(process_nums-1)*nums:])
for iz in range(process_nums):
p = Process(target =earth_cal1, args =(xyz_data_list[iz],line_list))
li_child_porc.append(p)
p.start()
for p in li_child_porc:
p.join()
line_frame = pd.DataFrame(line_list, columns = [ 'Point','North(m)','East(m)','H(m)','Earth_mag(nT)'])
try:
line_frame.sort_values(by = ['Point'],inplace = True)
except:
line_frame = line_frame
end_time = datetime.datetime.now()
use_time = str(end_time - start_time)
win32api.MessageBox(0, "Finish,用时"+use_time, "提醒",win32con.MB_OK)
使用单进程处理5000行
用时1分26秒,单进程效率 约55-60it/s
某一CPU占用率较高
使用4进程处理5000行
用时1分25秒,单进程效率10-13it/s
并且此时CPU利用率不高
也试过使用pool, pool.map 结果相近,并无明显提升
由于实际数据每天需处理几万行甚至是十几万行,所以想提高效率,求高人帮忙。
为了简化问题,直接用最简单的代码测试单进程和多进程,结果如下:
#单进程
from random import random
import time
def task(n):
a = random()
b = random()
return a+b
start = time.time()
for i in range(10**8):
task(i)
end = time.time()
span= end-start
print("单进程用时 %s seconds"%span)
#多进程
from random import random
from multiprocessing.dummy import Process,Pool
import time
def task(n):
a = random()
b = random()
return a+b
start = time.time()
pool = Pool(4)
pool.map(task,range(10**8))
end = time.time()
span= end-start
print("多进程用时 %s seconds"%span)
对比结果为 单进程27秒,多进程37秒,如图
【python使用multiprocessing多进程效率优化】
你可以尝试这些思路,供给你作为参考:
1.让关键代码依赖于外部包
2.排序时使用键(key)
3.优化循环
4.使用较新版本的Python
5.尝试多种编码方法
6.交叉编译应用程序
使用Python cProfile模块对脚本进行性能评估,找到瓶颈所在的地方,然后再进行优化
https://stackoverflow.com/questions/582336/how-do-i-profile-a-python-script
你的data划分写得不对,应该是
nums = math.ceil(data_nums/process_nums)
for i in range(process_nums):
xyz_data_list.append(xyz_dat[i*nums : (i+1)*nums])
多进程适用于计算密集型的任务,如果用来处理IO密集型任务,速度反倒会更慢,因为要做任务分割、结果汇集和进程管理。题主的代码没有缩进,无法阅读,但隐约可见文件处理和数据分割,多处使用了列表的append方法,这些都不是计算密集型任务的特点。如有兴趣,可参考我的这一篇博文。
分段多开几个程序 因为python 特性没法多开进程 所以你 分别 运行 两次代码即可 开启两个进程 三个就三个进程
cpu 有几个进行就运行几个程序
让关键代码依赖于外部包
换一个更多核的CPU?