给定2个大型3D点阵列(我将调用第一个"源"和第二个"目标"),我需要一个可以返回索引的函数"目的地"哪些匹配"来源"最接近这个限制:我只能使用numpy ...所以没有scipy,pandas,numexpr,cython ......
要做到这一点,我写了一个函数based on the "brute force" answer to this question。我遍历源元素,从目标中找到最接近的元素并返回其索引。由于性能问题,再次因为我只能使用numpy,我尝试多线程来加速它。以下是线程和非线程函数以及它们在8核机器上的速度比较。
import timeit
import numpy as np
from numpy.core.umath_tests import inner1d
from multiprocessing.pool import ThreadPool
def threaded(sources, destinations):
# Define worker function
def worker(point):
dlt = (destinations-point) # delta between destinations and given point
d = inner1d(dlt,dlt) # get distances
return np.argmin(d) # return closest index
# Multithread!
p = ThreadPool()
return p.map(worker, sources)
def unthreaded(sources, destinations):
results = []
#for p in sources:
for i in range(len(sources)):
dlt = (destinations-sources[i]) # difference between destinations and given point
d = inner1d(dlt,dlt) # get distances
results.append(np.argmin(d)) # append closest index
return results
# Setup the data
n_destinations = 10000 # 10k random destinations
n_sources = 10000 # 10k random sources
destinations= np.random.rand(n_destinations,3) * 100
sources = np.random.rand(n_sources,3) * 100
#Compare!
print 'threaded: %s'%timeit.Timer(lambda: threaded(sources,destinations)).repeat(1,1)[0]
print 'unthreaded: %s'%timeit.Timer(lambda: unthreaded(sources,destinations)).repeat(1,1)[0]
Retults:
threaded: 0.894030461056
unthreaded: 1.97295164054
多线程看起来很有用,但我希望在我处理的真实数据集要大得多的情况下增加2倍以上。
我们将非常感谢所有提高性能的建议(在上述限制范围内)!
答案 0 :(得分:1)
好的,我一直在阅读关于python的Maya文档,我得出了这些结论/猜测:
由于上述原因,我说它最好避免使用线程。由于GIL problem,这是一个常见问题,有几种方法可以做到这一点。
multiprocessing
。即使你的自定义python发行版没有包含它,你也可以使用一个工作版本,因为它是纯粹的python代码。 multiprocessing
不会受到GIL的影响,因为它会产生单独的进程。另外,如果你正在使用外部模块,请注意尝试匹配maya的版本。这可能是因为您无法构建scipy
的原因。当然,scipy
拥有庞大的代码库,而Windows平台的构建能力并不是最有弹性的。