Domanda

Ad esempio, quanta memoria è necessaria per memorizzare un elenco di un milione (32 bit) di numeri interi?

alist = range(1000000) # or list(range(1000000)) in Python 3.0
È stato utile?

Soluzione 2

Link utili:

Come ottenere le dimensioni della memoria / l'utilizzo dell'oggetto python

Dimensioni della memoria degli oggetti Python?

se inserisci i dati nel dizionario, come calcoliamo la dimensione dei dati ?

Tuttavia non danno una risposta definitiva. La strada da percorrere:

  1. Misura la memoria utilizzata dall'interprete Python con / senza l'elenco (usa gli strumenti del sistema operativo).

  2. Utilizza un modulo di estensione di terze parti che definisce una sorta di sizeof (PyObject).

Aggiorna :

Ricetta 546530: Dimensione degli oggetti Python (rivisto)

import asizeof

N = 1000000
print asizeof.asizeof(range(N)) / N
# -> 20 (python 2.5, WinXP, 32-bit Linux)
# -> 33 (64-bit Linux)

Altri suggerimenti

" Dipende. " Python alloca spazio per gli elenchi in modo tale da ottenere tempo costante ammortizzato per aggiungere elementi a l'elenco.

In pratica, ciò che significa con l'implementazione corrente è ... l'elenco ha sempre spazio assegnato per un numero di elementi di potenza di due. Quindi il range (1000000) assegnerà effettivamente un elenco abbastanza grande da contenere 2 ^ 20 elementi (~ 1.045 milioni).

Questo è solo lo spazio richiesto per memorizzare la struttura dell'elenco stessa (che è una matrice di puntatori agli oggetti Python per ciascun elemento). Un sistema a 32 bit richiederà 4 byte per elemento, un sistema a 64 bit utilizzerà 8 byte per elemento.

Inoltre, è necessario spazio per memorizzare gli elementi effettivi. Questo varia ampiamente. Per numeri interi piccoli (da -5 a 256 attualmente), non è necessario spazio aggiuntivo, ma per numeri più grandi Python alloca un nuovo oggetto per ogni numero intero, che impiega 10-100 byte e tende a frammentare la memoria.

In conclusione: è complicato e gli elenchi Python sono non un buon modo per archiviare grandi strutture di dati omogenee. Per questo, usa il modulo array o, se hai bisogno di fare matematica vettoriale, usa NumPy.

PS-Tuple, a differenza delle liste, non sono non progettate per avere elementi aggiunti progressivamente a loro. Non so come funzioni l'allocatore, ma non penso nemmeno di usarlo per grandi strutture di dati :-)

Indirizzamento " tupla " parte della domanda

La dichiarazione di PyTuple di CPython in una tipica configurazione di build si riduce a questo:

struct PyTuple {
  size_t refcount; // tuple's reference count
  typeobject *type; // tuple type object
  size_t n_items; // number of items in tuple
  PyObject *items[1]; // contains space for n_items elements
};

La dimensione dell'istanza di PyTuple è fissa durante la sua costruzione e non può essere modificata in seguito. Il numero di byte occupati da PyTuple può essere calcolato come

  

sizeof (size_t) x 2 + sizeof (void *) x (n_items + 1) .

Questo dà superficiale dimensione della tupla. Per ottenere la dimensione piena devi anche aggiungere il numero totale di byte consumati dal grafico degli oggetti radicato nella matrice PyTuple :: items [] .

Vale la pena notare che le routine di costruzione della tupla assicurano che venga mai creata una sola istanza di tupla vuota (singleton).

Riferimenti: Python.h , object.h , tupleobject.h , tupleobject.c

  

Una nuova funzione, getsizeof () , accetta a   Oggetto Python e restituisce l'importo   di memoria utilizzata dall'oggetto, misurata   in byte. Restituiscono gli oggetti incorporati   risultati corretti; terzo   le estensioni non possono, ma possono definire a   Metodo __sizeof __ () per restituire la dimensione dell'oggetto.

kveretennicov@nosignal:~/py/r26rc2$ ./python
Python 2.6rc2 (r26rc2:66712, Sep  2 2008, 13:11:55) 
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2
>>> import sys
>>> sys.getsizeof(range(1000000))
4000032
>>> sys.getsizeof(tuple(range(1000000)))
4000024

Ovviamente i numeri restituiti non includono la memoria consumata dagli oggetti contenuti (sys.getsizeof (1) == 12).

Questo è specifico dell'implementazione, ne sono abbastanza sicuro. Certamente dipende dalla rappresentazione interna degli interi - non si può presumere che saranno archiviati come 32 bit poiché Python ti dà numeri interi arbitrariamente grandi, quindi forse i piccoli ints sono memorizzati in modo più compatto.

Sul mio Python (2.5.1 su Fedora 9 su core 2 duo) il VmSize prima dell'allocazione è 6896kB, dopo è 22684kB. Dopo un altro milione di assegnazioni di elementi, VmSize passa a 38340 KB. Ciò indica molto grossolanamente circa 16000 KB per 1000000 numeri interi, ovvero circa 16 byte per numero intero. Ciò suggerisce un lotto di spese generali per l'elenco. Prenderei questi numeri con un grosso pizzico di sale.

Sono diffidente sul perché me lo stai chiedendo. Stai cercando di capire quanta memoria ti servirà per una data implementazione? Supponiamo che leggerai 10.000.000 di widget e vorresti sapere quanta RAM funzionerà?

In questo caso, piuttosto che cercare di capire quanta RAM impiega ciascun widget, capire quanta RAM, diciamo, 10.000 widget impiegano e moltiplicarsi per ottenere le dimensioni effettive.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top