繁体   English   中英

如何在Mac上更快地在python中建立巨大的循环?

[英]How to make huge loops in python faster on mac?

我是计算机科学专业的学生,​​我要做的一些事情要求我在具有双核i5的Macbook上运行巨大的循环。 有些循环需要5到6个小时才能完成,但它们仅占用我25%的CPU。 有没有办法使这个过程更快? 我无法更改循环,但是有没有办法使它们运行得更快?

谢谢

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

可以肯定的是: 每次使用range(<a huge number>) Python 2.7都必须生成大量列表并浪费大量内存。

尝试改用xrange函数。 它不会立即创建那个巨大的列表,而是会懒惰地产生序列的成员。


但是,如果您要使用Python 3(这是Python的现代版本和未来),您会发现它的range甚至比Python 2中的xrange更凉快。

您可以将其分为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 ,其中n是计算机上的处理器数量。

test_false_pos函数修改为采用三个参数:

  • times是运行循环的次数。
  • i被传递到结果。
  • q是将结果添加到的队列。

该函数循环times倍,那么地方isumA到队列中进行进一步的处理。

主线程( full_test )等待每个线程完成,然后将结果放在results列表中的适当位置。 列表完成后,将其展平,并计算平均值并返回。

考虑研究Numba和Jit(及时编译器)。 它适用于基于Numpy的功能。 它可以处理一些python例程,但主要用于加快数值计算的速度,尤其是带循环的计算(例如执行cholesky rank-1的上/下日期)。 我认为它不适用于BloomFilter,但是了解它通常非常有帮助。

如果您必须在流中将其他包与numpy一起使用,请将繁重的numpy例程分成各自的函数,然后在该函数之上抛出@jit装饰器。 然后将它们放入带有普通python内容的流中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM