2

次のコードは作業スレッドで実行され、一時停止/レポートコマンドなどを受信して​​、うまくスピンします。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()

注:エラトステネスのふるいを使用してアルゴリズムを最適化し、おそらくページフォールトを削減できることは知っていますが、それは重要ではありません。正確な理由、または少なくとも最悪の犯罪者を特定しようとしています。ページフォールトなので、将来同じようなことをするのを避けることができます。このアルゴリズムは、「ばかげて高価で単純な作業スレッド」が必要な場合に、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()
4

2 に答える 2

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
    ...

編集: への呼び出しのNone代わりに使用できることを指摘してくれた @John Gaines Jr. に感謝します。len(self.results)it.islice()

于 2012-09-10T17:26:57.593 に答える
3

Python チュートリアルのリストセクションから:

すべてのスライス操作は、要求された要素を含む新しいリストを返します。これは、次のスライスがリスト a の浅いコピーを返すことを意味します。

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

したがって、 for ループでは、ビットself.results[1:]は結果リストのコピーになります。このルーチンが何度も呼び出されると、非常に簡単にメモリ スラッシングが発生する可能性があります。

于 2012-09-10T17:20:36.033 に答える