さて、本当に最適化が必要な Python コードを取得しました。
- これは、小さな (80x60 ピクセル) 画像に対する Game-of-Life 反復であり、そこから RGB 値を抽出します。
- 現在、ネストされた for ループを使用しています。これらの for ループをより高速な c 関数に交換したいのです
map()
が、そうすると、x、y 値を取得する方法や、関数のスコープ外で定義されたローカル値を取得する方法がわかりません。定義する必要があります。 map()
この for ループの現在のセットよりも速く使用できますか? どうすればそれを使用してもx、yを取得できますか?- 私は現在pygame Surfacesを使用しており、モジュールを試しました
surfarray/pixelarray
が、すべてのピクセルを変更/取得しているため、Surface.get_at()/set_at()
. - また、少し無関係です... Pythonが数字のリストをトラバースせず、他の言語のように数字をインクリメントするだけの場合、これはより速くできると思いますか? Python に通常の for() と foreach() が含まれていないのはなぜですか?
- そこにある条件文の量もおそらく物事を遅くしますよね?最も遅い部分は、隣人のチェックです (リスト n を構築する場所)... そのビット全体を 2D 配列のスライス アクセスに置き換えましたが、正しく動作しません。
コードの編集済みバージョン:
xr = xrange(80)
yr = xrange(60)
# surface is an instance of pygame.Surface
get_at = surface.get_at()
set_at = surface.set_at()
for x in xr:
# ....
for y in yr:
# ...
pixelR = get_at((x,y))[0]
pixelG = get_at((x,y))[1]
pixelB = get_at((x,y))[2]
# ... more complex stuff here which changes R,G,B values independently of each other
set_at((x,y),(pixelR,pixelG,pixelB))
関数の完全版:
# xr, yr = xrange(80), xrange(60)
def live(surface,xr,yr):
randint = random.randint
set_at = surface.set_at
get_at = surface.get_at
perfect = perfectNeighbours #
minN = minNeighbours # All global variables that're defined in a config file.
maxN = maxNeighbours #
pos = actual # actual = (80,60)
n = []
append = n.append
NEIGHBOURS = 0
for y in yr: # going height-first for aesthetic reasons.
decay = randint(1,maxDecay)
growth = randint(1,maxGrowth)
for x in xr:
r, g, b, a = get_at((x,y))
del n[:]
NEIGHBOURS = 0
if x>0 and y>0 and x<pos[0]-1 and y<pos[1]-1:
append(get_at((x-1,y-1))[1])
append(get_at((x+1,y-1))[1])
append(get_at((x,y-1))[1])
append(get_at((x-1,y))[1])
append(get_at((x+1,y))[1])
append(get_at((x-1,y+1))[1])
append(get_at((x+1,y+1))[1])
append(get_at((x,y+1))[1])
for a in n:
if a > 63:
NEIGHBOURS += 1
if NEIGHBOURS == 0 and (r,g,b) == (0,0,0): pass
else:
if NEIGHBOURS < minN or NEIGHBOURS > maxN:
g = 0
b = 0
elif NEIGHBOURS==perfect:
g += growth
if g > 255:
g = 255
b += growth
if b > growth: b = growth
else:
if g > 10: r = g-10
if g > 200: b = g-100
if r > growth: g = r
g -= decay
if g < 0:
g = 0
b = 0
r -= 1
if r < 0:
r = 0
set_at((x,y),(r,g,b))