2017-05-11 2 views
0

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.

+0

Welche Operationen werden in einer Datei ausgeführt? Vielleicht treffen Sie einfach das Speicherlimit. –

+0

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

+0

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

Antwort

0

Mailing list Ansprüche:

So können Sie 600KB des Quellcodes oder 350KB von pyc ohne jegliche Probleme haben.

Gleichzeitig ist die Anzahl der Locals (und damit Funktionsargumente) begrenzt. Ebenso ist die Eindringtiefe ebenfalls begrenzt. Die Grenzen sind 255 bzw. 100, und Sie würden einen schönen Fehler bekommen, wenn Sie diese überschreiten.

Verwandte Themen