是什么导致这个python代码中的135k / sec页面错误? (试验筛分)

时间:2012-09-10 16:59:27

标签: python primes page-fault

以下代码在工作线程中执行,并且很高兴旋转,接收暂停/报告命令等。我认为它们是软错误,因为我没有RAM使用问题而且我的硬盘驱动器没有融化在周末,这与我让结果累积的时间有关,因为我在几天前启动它时只会出现约50页的错误。

“counter”属性目前为22,496,115,“results”有1,418,641个元素。 拍摄“结果”是因为我感觉相反并且在1开始列表。

def run(self):
    while self.keep_running:
        self.lock.acquire()

        is_prime = True
        self.counter += 1
        cutoff_val = pow(self.counter,.5)
        for number in self.results[1:]:
            if number > cutoff_val:
                break

            if self.counter % number == 0:
                is_prime = False
                break

        if is_prime:
            self.results.append(self.counter)

        self.lock.release()

注意:我知道我可以使用Sieve of Eratosthenes来优化算法并可能减少页面错误,但这不是重点:我正在试图查明确切的原因 - 或者至少是最糟糕的罪犯 - 在页面错误背后,所以我可以避免在将来做同样的事情。当我需要一个“愚蠢的,简单的工作线程”时,该算法仅用于测试UI响应性。

根据要求提供其他设置:

def __init__(self):
    self.counter = 0
    self.keep_running = False;
    self.lock = threading.Lock()
    self.results = list()

def __call__(self, *args):
    if not self.keep_running:
        self.keep_running = True
        self.run()

2 个答案:

答案 0 :(得分:4)

我认为@John Gaines Jr.指出了你需要改变的事情。如果您的列表非常大,那么您不希望像那样复制它。

这是一种循环使用与self.results[1:]相同的值但不进行复制的好方法:

res = iter(self.results)  # get an iterator for the list values
next(res)  # iterate once to throw away first value
for number in res:
    # same code you already have goes here
    ...

编辑:上面的代码是正确和简单的,但不能很好地扩展。我想到了这一点,并认为itertools中必须有一些东西,而且确实存在:

import itertools as it
res = it.islice(self.results, 1, None)
for number in res:
    # same code you already have goes here
    ...
编辑:感谢@John Gaines Jr.指出在调用None时可以使用len(self.results)代替it.islice()

答案 1 :(得分:3)

来自Python教程Lists部分:

所有切片操作都返回包含所请求元素的新列表。这意味着以下切片返回列表a的浅表副本:

>>> a[:]
['spam', 'eggs', 100, 1234]

因此,在for循环中,位self.results[1:]会生成结果列表的副本。如果反复调用此例程,很容易导致内存抖动。

相关问题