我有以下代码,我正在一些大数据上运行它(2小时的处理时间),我正在研究CUDA来加速GPU,但与此同时任何人都可以提出优化以下代码的方法吗?
我正在从数据集“ T”中获取一个3D点,并找到与另一个点数据集“ B”具有最小距离的点
通过将结果首先发送到列表然后插入数据库表,可以节省任何时间吗?
欢迎所有建议
conn = psycopg2.connect("<details>")
cur = conn.cursor()
for i in range(len(B)):
i2 = i + 1
# point=T[i]
point = B[i:i2]
# print(B[i])
# print(B[i:i2])
disti = scipy.spatial.distance.cdist(point, T, metric='euclidean').min()
print("Base: ", end='')
print(i, end='')
print(" of ", end='')
print(len(B), end='')
print(" ", end='')
print(disti)
cur.execute("""INSERT INTO pc_processing.pc_dist_base_tmp (x,y,z,dist) values (%s, %s, %s, %s)""",
(xi[i], yi[i], zi[i], disti))
conn.commit()
cur.close()
代码更新:
conn = psycopg2.connect("dbname=kap_pointcloud host=localhost user=postgres password=Gnob2009")
cur = conn.cursor()
disti = []
for i in range(len(T)):
i2 = i + 1
point = T[i:i2]
disti.append(scipy.spatial.distance.cdist(point, B, metric='euclidean').min())
print("Top: " + str(i) + " of " + str(len(T)))
弄清楚语法后,将代码插入此处
@@@@@@@@@@编辑@@@@@@@@@
Alex提供了大量帮助的解决方案
cur = conn.cursor()
# list for accumulating insert-params
from scipy.spatial.distance import cdist
insert_params = []
for i in range(len(T)):
XA = [B[i]]
disti = cdist(XA, XB, metric='euclidean').min()
insert_params.append((xi[i], yi[i], zi[i], disti))
print("Top: " + str(i) + " of " + str(len(T)))
# Only one instruction to insert everything
cur.executemany("INSERT INTO pc_processing.pc_dist_top_tmp (x,y,z,dist) values (%s, %s, %s, %s)",
insert_params)
conn.commit()
要进行时间比较,请:
初始代码为:0:00:50.225644
没有多行打印:0:00:47.934012
将提交移出循环:0:00:25.411207
我假设要使其更快的唯一方法是使CUDA正常工作?
答案 0 :(得分:3)
有2种解决方案
1)如果len(B)非常大,请尝试执行单次提交或分块提交。
2)您可以准备要插入的数据列表并进行批量插入。
例如:
insert into pc_processing.pc_dist_base_tmp (x, y, z, dist) select * from unnest(array[1, 2, 3, 4], array[1, 2, 3, 4]);
答案 1 :(得分:1)
尝试在循环结束时提交,而不是每次迭代都提交
答案 2 :(得分:1)
好。让我们从评论中收集所有建议。
commit
尽可能少见,不要print
conn = psycopg2.connect("<details>")
cur = conn.cursor()
insert_params=[]
for i in range(len(B)):
i2 = i + 1
point = B[i:i2]
disti = scipy.spatial.distance.cdist(point, T, metric='euclidean').min()
cur.execute("""INSERT INTO pc_processing.pc_dist_base_tmp (x,y,z,dist) values (%s, %s, %s, %s)""", (xi[i], yi[i], zi[i], disti))
conn.commit() # Note that you commit only once. Be careful with **realy** big chunks of data
cur.close()
如果您确实需要在循环中使用调试信息,请使用logging
。
您将可以在需要时打开/关闭日志记录信息。
executemany
进行救援conn = psycopg2.connect("<details>")
cur = conn.cursor()
insert_params=[] # list for accumulating insert-params
for i in range(len(B)):
i2 = i + 1
point = B[i:i2]
disti = scipy.spatial.distance.cdist(point, T, metric='euclidean').min()
insert_params.append((xi[i], yi[i], zi[i], disti))
# Only one instruction to insert everything
cur.executemany("INSERT INTO pc_processing.pc_dist_base_tmp (x,y,z,dist) values (%s, %s, %s, %s)", insert_params)
conn.commit()
cur.close()
psycopg2
。使用批量操作写入cur.execute
文件而不是conn.commit
,csv
。
然后从创建的文件中使用COPY。
批量解决方案必须提供最终的性能,但需要努力才能使其正常工作。
选择适合自己的人-您需要多少速度。
祝你好运