我有以下代码,我正在一些大数据上运行它(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)))
一旦我弄清楚语法,插入代码就转到此处
@@@@@@ 编辑 @@@@@@@@
在亚历克斯的大力帮助下的解决方案
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 工作?
有 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. 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
.
在需要时打开/关闭日志记录信息。
建议2. 救援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()
建议3.根本不要使用psycopg2
。使用批量操作
conn.commit
写csv
文件代替cur.execute
。然后使用从创建的文件复制。
BULK 解决方案必须提供终极性能,但需要努力使其发挥作用。
选择适合自己的 - 您需要多少速度。
祝你好运
尝试在循环完成时提交,而不是每次迭代