私は現在、特定の2Dポイントが "合法"である場合、つまりグリッドの境界内にあるかどうかを複数回チェックしなければならないプロジェクトを行っています。前に訪問された。グリッドは固定されたH x W
のサイズを持っているので、私はおそらくセットではなく2Dのルックアップテーブルを格納できると思いました。驚いたことに、単純な配列検索でO(1)
とは対照的に、(理論的には)O(logn)
操作であっても、セットに表示されているかどうかを確認するよりもかなり遅いです。リストルックアップが設定されたルックアップよりも遅い
まず試してみてください。
class PointSet:
def __init__(self, h, w):
if h <= 0 or w <= 0:
raise ValueError("Invalid size")
self.h = h
self.w = w
self.lookup = [[False for _ in range(w)] for _ in range(h)]
self.size = 0
def add(self, point):
r, c = point
self.lookup[r][c] = True
self.size += 1
def remove(self, point):
r, c = point
self.lookup[r][c] = False
self.size -= 1
def __contains__(self, point):
r, c = point
return 0 <= r < self.h and 0 <= c < self.w and self.lookup[r][c]
def __bool__(self):
return self.size != 0
def __len__(self):
return self.size
# H, W = ...
# pointset = PointSet(H, W)
# if (3, 5) in pointset:
# ...
2回目の試行:
# pointset = set()
# if (3, 5) in pointset:
# ...
第二のコードがかなり速く実行されます。それはなぜですか?
両方のセットとリストには「複雑なアイテムを取得する」という複雑さがあるので、ここでの違いは組み込み関数(C言語で実装される可能性が高い)ですが、カスタム 'PointSet'はそれゆえ遅くなります。 –
@Rawing:これも私が考えていたことですが、私は複雑さを台無しにするような何かに気づいていないかもしれないと思っていました。ありがとうございました – shooqie
私は 'add()'メソッドを呼び出すたびに、私のセットのサイズを増やしたことに気付きました。それは何とか私のコードではまだ動作します。しかし、実行時間はまったく変わっていない。 – shooqie