首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在mac上更快地实现python中的大型循环?

如何在mac上更快地实现python中的大型循环?
EN

Stack Overflow用户
提问于 2016-10-08 03:01:22
回答 3查看 1.2K关注 0票数 0

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

谢谢

Mac OS 10.11 Python 2.7 (我必须使用2.7)与Anaconda上的IDLE或Spyder

以下是耗时15分钟的示例代码:

代码语言:javascript
复制
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
EN

回答 3

Stack Overflow用户

发布于 2016-10-08 03:05:32

当然,每次使用range(<a huge number>)时,Python2.7都必须生成大量列表并浪费大量内存。

请尝试使用xrange函数。它不会立即创建一个巨大的列表,它会懒惰地生成序列的成员。

但是如果您使用Python3(Python3是Python3的现代版本,也是Python2的未来版本),您会发现range比Python2中的xrange更酷、更快。

票数 4
EN

Stack Overflow用户

发布于 2016-10-08 03:13:40

你可以把它分成4个循环:

代码语言:javascript
复制
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次,然后将isumA放入队列中进行进一步处理。

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

票数 3
EN

Stack Overflow用户

发布于 2016-10-08 03:26:01

考虑研究Numba和Jit (即时编译器)。它适用于基于Numpy的函数。它可以处理一些python例程,但主要是为了加速数值计算,特别是那些有循环的计算(比如做cholesky的秩1上升/下降)。我不认为它会在BloomFilter上工作,但了解它通常是非常有帮助的。

如果您必须在流中使用numpy的其他包,请将繁重的numpy例程分离到它们自己的函数中,并在该函数的顶部抛出一个@jit装饰器。然后用普通的python工具把它们放入你的流中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39924176

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档