unire Serializzazione lista Python-metodo più veloce




unire due liste python (5)

Ho bisogno di caricare (de-serializzare) un elenco precompilato di interi da un file in uno script Python (in una lista Python). L'elenco è di grandi dimensioni (fino a milioni di elementi) e posso scegliere il formato in cui lo memorizzo, purché il caricamento sia il più veloce.

Qual è il metodo più veloce e perché?

  1. Utilizzo import su un file .py che contiene solo l'elenco assegnato a una variabile
  2. Usando il load cPickle
  3. Qualche altro metodo (forse numpy ?)

Inoltre, come si può eseguire una valutazione affidabile di queste cose?

Addendum: misurare questo in modo affidabile è difficile, perché l' import è memorizzata nella cache in modo che non possa essere eseguita più volte in un test. Il caricamento con pickle diventa anche più veloce dopo la prima volta, probabilmente perché il precaching di pagina da parte del sistema operativo. Caricamento di 1 milione di numeri con cPickle richiede 1,1 secondi alla prima esecuzione e 0,2 secondi alle successive esecuzioni dello script.

Intuitivamente sento che cPickle dovrebbe essere più veloce, ma apprezzerei i numeri (questa è una vera sfida da misurare, credo).

E sì, è importante per me che questo si esibisca rapidamente.

Grazie


Per il benchmarking, consultare il modulo timeit nella libreria standard Python. Per vedere qual è il modo più veloce, implementare tutti i modi in cui puoi pensare e misurarli con timeit.

Pensiero casuale: a seconda di cosa stai facendo esattamente, potresti trovarlo più veloce per memorizzare "serie di numeri interi" nello stile utilizzato nei file .newsrc :

1, 3-1024, 11000-1200000

Se hai bisogno di verificare se qualcosa è in quel set, allora il caricamento e l'abbinamento con una tale rappresentazione dovrebbero essere tra i modi più veloci. Ciò presuppone che i tuoi set di numeri interi siano ragionevolmente densi, con lunghe sequenze consecutive di valori adiacenti.


Direi che cPickle sarà il più veloce se hai davvero bisogno di qualcosa in una lista.

Se è possibile utilizzare un array , che è un tipo di sequenza incorporato, l'ho cronometrato a un quarto di secondo per 1 milione di interi:

from array import array
from datetime import datetime

def WriteInts(theArray,filename):
    f = file(filename,"wb")
    theArray.tofile(f)
    f.close()

def ReadInts(filename):
    d = datetime.utcnow()
    theArray = array('i')
    f = file(filename,"rb")
    try:
        theArray.fromfile(f,1000000000)
    except EOFError:
        pass
    print "Read %d ints in %s" % (len(theArray),datetime.utcnow() - d)
    return theArray

if __name__ == "__main__":
    a = array('i')
    a.extend(range(0,1000000))
    filename = "a_million_ints.dat"
    WriteInts(a,filename)
    r = ReadInts(filename)
    print "The 5th element is %d" % (r[4])

Hai sempre bisogno di caricare l'intero file? In caso contrario, upack_from () potrebbe essere la soluzione migliore. Supponiamo che tu abbia 1000000 numeri interi, ma ti piacerebbe caricare solo quelli da 50000 a 50099, dovresti fare:

import struct
intSize = struct.calcsize('i') #this value would be constant for a given arch
intFile = open('/your/file.of.integers')
intTuple5K100 = struct.unpack_from('i'*100,intFile,50000*intSize)

"come si può eseguire una valutazione affidabile di queste cose?"

Non capisco la domanda.

Scrivi un sacco di piccole funzioni per creare e salvare la tua lista in varie forme.

Scrivi un sacco di piccole funzioni per caricare le tue liste nelle loro varie forme.

Scrivi una piccola funzione del timer per ottenere il tempo di avvio, esegui la procedura di caricamento alcune decine di volte (per ottenere una media solida abbastanza lunga da impedire che il rumore di pianificazione del sistema operativo superi le tue misurazioni).

Riassumi i tuoi dati in un piccolo report.

Cosa non è affidabile a riguardo?

Ecco alcune domande non correlate che mostrano come misurare e confrontare le prestazioni.

Converti un elenco di interi in un numero?

Concatenazione di stringhe e sostituzione di stringhe in Python


Per aiutarti con i tempi, la libreria Python fornisce il modulo timeit :

Questo modulo fornisce un modo semplice per misurare piccoli bit di codice Python. Ha sia la riga di comando che le interfacce richiamabili. Evita un numero di trap comuni per misurare i tempi di esecuzione.

Un esempio (dal manuale) che confronta il costo dell'utilizzo di hasattr() contro try/except per testare gli attributi degli oggetti mancanti e presenti:

% timeit.py 'try:' '  str.__nonzero__' 'except AttributeError:' '  pass'
100000 loops, best of 3: 15.7 usec per loop
% timeit.py 'if hasattr(str, "__nonzero__"): pass'
100000 loops, best of 3: 4.26 usec per loop
% timeit.py 'try:' '  int.__nonzero__' 'except AttributeError:' '  pass'
1000000 loops, best of 3: 1.43 usec per loop
% timeit.py 'if hasattr(int, "__nonzero__"): pass'
100000 loops, best of 3: 2.23 usec per loop






caching