Ich kompiliere in Python 3 (.4.4) und habe ein Programm generiert, das 250.000 Zeilen lang ist. Als ich versuchte, es auszuführen, stürzte Python ab: Windows (10) berichtete "python.exe funktioniert nicht mehr". Kürzere Versionen der "gleichen" Ausgabe laufen OK, also frage ich mich, ob das Problem ist, dass mein Programm zu lang ist und wenn ja, wie kann ich das Limit erhöhen?Was begrenzt die Größe eines Python-Moduls?
Bitte beachten Sie, dass ich nicht an "Lösungen" interessiert bin, wo meine Ausgabe in kleinere Stücke faktorisiert wird. Eine monolithische Ausgabedatei ist der Teil der Problemspezifikation.
Hier ist, was das Programm wie folgt aussieht:
import os, sys
from random import randint, seed
from datetime import datetime
DEAD = '_'
ALIVE = '1'
cells = [] # Will be an array of max_row+2 rows each of max_col+2 columns.
# Create initial population of cells
seed(1.3)
def repeat_run(max_run):
print('%20s %20s %20s' % ('Time', 'Rate', 'Density'))
for run in range(max_run):
blank_row = [ DEAD for col in range(152) ]
for row in range(152):
cells.append(blank_row.copy())
pop = 0
for row in range(1, 152-1):
for col in range(1, 152-1):
if randint(0, 1) == 0:
cells[ row ][ col ] = ALIVE
pop += 1
time, rate, density = simulate(cells, pop)
print('%20.5f %20.5f %20.5f' % (time, rate, density))
print()
def num_neighb(row, col):
count = 0
for col_inc in range(-1, 2):
x = col + col_inc
for row_inc in range(-1, 2):
y = row + row_inc
if cells[ y ][ x ] == ALIVE:
count += 1
return count
def simulate(cells, pop):
# Global tally of all cells that ever lived (for calculating average
# density over the entire run).
grand_total = pop
start = datetime.now()
for gen in range(10):
pop = 0 # Number of live cells in next generation
# Initialise next generation of cells
next_gen = [ [ DEAD for col in range(152) ] for col in range(152) ]
# Apply birth/death rules
nn = num_neighb(1, 1)
if cells[ 1 ][ 1 ] == DEAD:
if nn == 3:
next_gen[ 1 ][ 1 ] = ALIVE
pop += 1
else:
if nn == 3 or nn == 4:
next_gen[ 1 ][ 1 ] = ALIVE
pop += 1
# 250,000 lines later ...
nn = num_neighb(150, 150)
if cells[ 150 ][ 150 ] == DEAD:
if nn == 3:
next_gen[ 150 ][ 150 ] = ALIVE
pop += 1
else:
if nn == 3 or nn == 4:
next_gen[ 150 ][ 150 ] = ALIVE
pop += 1
grand_total += pop
# Copy next_gen to cells
for col in range(152):
for row in range(152):
cells[ row ][ col ] = next_gen[ row ][ col ]
end = datetime.now()
delta = (end - start).total_seconds()
return delta, 231040/delta, grand_total/231040
repeat_run(10)
Das vollständige Programm here zur Verfügung steht.
Danke für Ihre Gedanken.
Welche Operationen werden in einer Datei ausgeführt? Vielleicht treffen Sie einfach das Speicherlimit. –
Ist diese Größe aufgrund von Literalen in der Quelldatei? Beginnen Sie mit den neuesten 3.6, um nach Verbesserungen der Compiler-Effizienz zu suchen. Wahrscheinlich nicht. Ich erinnere mich, dass sich jemand damit beschäftigt hat, weil Python nicht genügend Speicher hatte, während er versuchte, ein großes Diktat-Literal zu parsen. Das Problem war eine Heap-Fragmentierung aufgrund schlechter Speicherverwaltung im Compiler. – eryksun
Gut 250.000 Zeilen von "1" (was eine legale Top-Level-Anweisung ist) verursachen keinen Ärger. Dann wieder, das ist kaum repräsentativ für ein nützliches Modul ... –