我制作了自己的合作出口商,即使它正在运作,也很慢。我假设问题来自于专门针对元素进行循环,并且基于this comment来自使用data.enrichedData.findAll{it.@datatable == "ROUTING"}.customer.each { println it.text() }
。
导出struct.pack
的挑战在于它是元组的一维向量。导出Nodes
的挑战是Faces
的每一行前面都有一个数字" 3"以int
格式。
我将整个代码放在这里,因为它可以作为MWE,也可以作为参考,如果有人想使用代码以层格式导出网格。
代码:
uchar
结果:
from __future__ import division
import numpy as np
import struct
import timeit
def Timeme(funct,var,NN=10,NNN=10):
for i in xrange(NN):
start =timeit.default_timer()
for t in xrange(NNN):
funct(*var)
end =timeit.default_timer()
print str(i)+': '+str((end - start)/NNN*1000)
# This function is fictitious. In reality the
# Nodes array is imported from another module
def MakeNodes(Nr,Nc):
Nodes=np.zeros(Nr*Nc,dtype=[('x', np.float32), ('y', np.float32), ('z', np.float32)])
x = np.linspace(0, (Nc-1), Nc, dtype=np.float32)
y = np.linspace((Nr-1),0 , Nr, dtype=np.float32)
xv, yv = np.meshgrid(x, y, sparse=False, indexing='xy')
Nodes['x']=xv.flatten()
Nodes['y']=yv.flatten()
Nodes['z']=(1/2-((Nodes['x']/Nc-1/2)**2+ (Nodes['y']/Nr-1/2)**2))*Nr/2
return Nodes
# Function below explained in https://stackoverflow.com/questions/44934631
def MakeFaces(Nr,Nc):
out = np.empty((Nr-1,Nc-1,2,3),dtype=int)
r = np.arange(Nr*Nc).reshape(Nr,Nc)
l1=r[:-1,:-1]
l2=r[:-1,1:]
l3=r[1:,:-1]
l4=r[1:,1:]
out[:,:, 0,0] = l2
out[:,:, 0,1] = l1
out[:,:, 0,2] = l3
out[:,:, 1,0] = l4
out[:,:, 1,1] = l2
out[:,:, 1,2] = l3
out.shape =(-1,3)
return out
def ExportPlyBinary(Nodes,Faces,file):
LN=len(Nodes)
LF=len(Faces)
header= \
"ply\n" \
"format binary_little_endian 1.0\n" \
"element vertex "+str(LN)+"\n" \
"property float x\n" \
"property float y\n" \
"property float z\n" \
"element face "+str(LF)+"\n" \
"property list uchar int vertex_indices\n" \
"end_header\n"
with open(file, 'wb') as fp:
fp.write(header)
s = struct.Struct('<fff')
for nd in Nodes:
fp.write(s.pack(nd['x'],nd['y'],nd['z']))
s = struct.Struct('<Blll')
for fc in Faces:
fp.write(s.pack(3,fc[0],fc[1],fc[2]))
Nr=200
Nc=200
Nodes=MakeNodes(Nr,Nc)
Faces=MakeFaces(Nr,Nc)
Timeme(ExportPlyBinary,(Nodes,Faces,"Test.ply"))
Timeme(np.savez,("Test_np.ply", Nodes,Faces))
答案 0 :(得分:1)
为什么不使用可用的东西?
例如trimesh? https://pypi.python.org/pypi/trimesh
即使您不只是包的一小部分,您也可以从源代码中复制和调整此部分。 (当然提到作者)
答案 1 :(得分:0)
我按照@ max9111的建议检查了Trimesh
,并且能够创建更高效的功能。关键思想(在我的理解中)是(1)通过创建新数组转换为正确的数据类型和顺序,以及(2)使用.tostring
函数。我最初避开了这个方向,因为它似乎浪费了记忆,但在这一点上,优势很明显。请注意,我的Nodes
数组已准备好应用.tostring
,但我会保持解决方案更加通用。
def NewExportPlyBinary(Nodes,Faces,file):
LN=len(Nodes)
LF=len(Faces)
header= \
"ply\n" \
"format binary_little_endian 1.0\n" \
"element vertex "+str(LN)+"\n" \
"property float x\n" \
"property float y\n" \
"property float z\n" \
"element face "+str(LF)+"\n" \
"property list uchar int vertex_indices\n" \
"end_header\n"
dtype_vertex = [('vertex', '<f4', (3))]
vertex = np.empty(LN, dtype=dtype_vertex)
vertex['vertex']=np.stack((Nodes['x'],Nodes['y'],Nodes['z']),axis=-1)
# vertex=Nodes
dtype_face = [('count', '<u1'),('index', '<i4', (3))]
faces = np.empty(LF, dtype=dtype_face)
faces['count'] = 3
faces['index'] = Faces
with open(file, 'wb') as fp:
fp.write(header)
fp.write(vertex.tostring())
fp.write(faces.tostring())
我现在为200x200示例获得以下时间:
0: 373.361611377 # original ExportPlyBinary
0: 20.5686725792 # numpy's savez
0: 4.85469689001 # NewExportPlyBinary
注意:当问题规模增加时,savez
和NewExportPlyBinary
之间的差异基本消失。