以下代码在工作线程中执行,并且很高兴旋转,接收暂停/报告命令等。我认为它们是软错误,因为我没有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()
答案 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:]
会生成结果列表的副本。如果反复调用此例程,很容易导致内存抖动。