我是一名计算机科学专业的学生,我做的一些事情需要我在具有双核心i5的Macbook上运行巨大的循环。有些循环需要5-6个小时才能完成,但它们只占用了我CPU的25%。有没有办法让这个过程更快?我不能改变我的循环,但有没有办法让它们跑得更快?
谢谢
Mac OS 10.11 Python 2.7 (我必须使用2.7)与Anaconda上的IDLE或Spyder
以下是耗时15分钟的示例代码:
def test_false_pos():
sumA = [0] * 1000
for test in range(1000):
counter = 0
bf = BloomFilter(4095,10)
for i in range(600):
bf.rand_inserts()
for x in range(10000):
randS = str(rnd.randint(0,10**8))
if bf.lookup(randS):
counter += 1
sumA[test] = counter/10000.0
avg = np.mean(sumA)
return avg发布于 2016-10-08 03:05:32
当然,每次使用range(<a huge number>)时,Python2.7都必须生成大量列表并浪费大量内存。
请尝试使用xrange函数。它不会立即创建一个巨大的列表,它会懒惰地生成序列的成员。
但是如果您使用Python3(Python3是Python3的现代版本,也是Python2的未来版本),您会发现range比Python2中的xrange更酷、更快。
发布于 2016-10-08 03:13:40
你可以把它分成4个循环:
import multiprocessing
def test_false_pos(times, i, q):
sumA = [0] * times
for test in range(times):
counter = 0
bf = BloomFilter(4095,10)
for i in range(600):
bf.rand_inserts()
for x in range(10000):
randS = str(rnd.randint(0,10**8))
if bf.lookup(randS):
counter += 1
sumA[test] = counter/10000.0
q.put([i, list(sumA)])
def full_test(pieces):
threads = []
q = multiprocessing.Queue()
steps = 1000 / pieces
for i in range(pieces):
threads.append(multiprocessing.Process(target=test_false_pos, args=(steps, i, q)))
[thread.start() for thread in threads]
results = [None] * pieces
for i in range(pieces):
i, result = q.get()
results[i] = result
# Flatten the array (`results` looks like this: [[...], [...], [...], [...]])
# source: https://stackoverflow.com/a/952952/5244995
sums = [value for result in results for val in result]
return np.mean(np.array(sums))
if __name__ == '__main__':
full_test(multiprocessing.cpu_count())这将运行n个进程,每个进程执行1/n_th的工作,其中_n是计算机上的处理器数量。
test_false_pos函数已修改为接受三个参数:
times是将loop.i传递到result.q的运行次数,是将结果添加到的队列。该函数循环times次,然后将i和sumA放入队列中进行进一步处理。
主线程(full_test)等待每个线程完成,然后将结果放在results列表中的适当位置。一旦列表完成,它将被展平,并计算并返回平均值。
发布于 2016-10-08 03:26:01
考虑研究Numba和Jit (即时编译器)。它适用于基于Numpy的函数。它可以处理一些python例程,但主要是为了加速数值计算,特别是那些有循环的计算(比如做cholesky的秩1上升/下降)。我不认为它会在BloomFilter上工作,但了解它通常是非常有帮助的。
如果您必须在流中使用numpy的其他包,请将繁重的numpy例程分离到它们自己的函数中,并在该函数的顶部抛出一个@jit装饰器。然后用普通的python工具把它们放入你的流中。
https://stackoverflow.com/questions/39924176
复制相似问题