我有一个函数:
1)将hdf5数据集读入为整数ascii代码
2)将ascii整数转换为characters...chr()函数
3)将字符连接到单个字符串函数中
在分析时,我发现大部分计算都花在了第2步上,即将ascii整数转换为字符。我通过使用以下命令对此调用进行了一定程度的优化:
''.join([chr(x) for x in file[dataSetName].value])由于我的解析函数似乎受cpu限制(整数到字符的转换),而不是i/o限制,所以我希望随着用于解析的内核数量的增加,可以获得更多/更少的线性速度提升。串行解析一个文件需要大约15个seconds...to解析10个文件(在我的12核机器上)需要大约150秒,而使用10个线程。也就是说,似乎根本没有增强。
我使用以下代码来启动我的线程:
threads=[]
timer=[]
threadNumber=10
for i,d in enumerate(sortedDirSet):
timer.append(time.time())
# self.loadFile(d,i)
threads.append(Thread(target=self.loadFileargs=(d,i)))
threads[-1].start()
if(i%threadNumber==0):
for i2,t in enumerate(threads):
t.join()
print(time.time()-timer[i2])
timer=[]
threads=[]
for t in threads:
t.join()任何帮助都将不胜感激。
发布于 2013-04-30 22:35:09
Python不能使用多核(由于GIL),除非您派生子进程(例如,使用multiprocessing )。因此,你不会得到任何的性能提升与繁衍线程的CPU限制的任务。
以下是使用multiprocessing和queue的脚本示例
from Queue import Empty # <-- only needed to catch Exception
from multiprocessing import Process, Queue, cpu_count
def loadFile(d, i, queue):
# some other stuff
queue.put(result)
if name == "main":
queue = Queue()
no = cpu_count()
processes = []
for i,d in enumerate(sortedDirSet):
p = Process(target=self.loadFile, args=(d, i, queue))
p.start()
processes.append(p)
if i % no == 0:
for p in processes:
p.join()
processes = []
for p in processes:
p.join()
results = []
while True:
try:
# False means "don't wait when Empty, throw an exception instead"
data = queue.get(False)
results.append(data)
except Empty:
break
# You have all the data, do something with it另一种(更复杂的)方法是使用pipe而不是queue。
生成进程,然后创建一个作业队列并(通过pipe)将它们发送给子进程(这样您就不必每次都创建一个进程),也会更有效率。但是这将会更加复杂,所以我们就让它这样吧。
发布于 2013-04-30 22:56:39
怪胎的答案是正确的,这将是GIL阻挠你的努力。
如果你要使用Python3,你可以用concurrent.futures很好地做到这一点。我相信PyPy也支持这个特性。
此外,你可以通过替换你的列表理解来提高代码的速度:
''.join([chr(x) for x in file[dataSetName].value])使用地图:
''.join(map(chr, file[dataSetName].value))我使用上述代码进行的测试(在大量随机列表上)显示,使用列表理解的时间为15.73秒,使用map的时间为12.44秒。
https://stackoverflow.com/questions/16302443
复制相似问题