Questo è un confronto tra le mele e le arance. Vedi http://redis.io/topics/benchmarks
Redis è un telecomando efficiente archivio dati. Ogni volta che viene eseguito un comando su Redis, viene inviato un messaggio al server Redis e, se il client è sincrono, si blocca in attesa della risposta. Quindi, oltre al costo del comando stesso, pagherai un viaggio di andata e ritorno in rete o un IPC.
Su hardware moderno, i roundtrip di rete o gli IPC sono sorprendentemente costosi rispetto ad altre operazioni. Ciò è dovuto a diversi fattori:
- la latenza grezza del mezzo (principalmente per la rete)
- la latenza dello scheduler del sistema operativo (non garantita su Linux/Unix)
- Gli errori nella cache di memoria sono costosi e la probabilità di errori nella cache aumenta mentre i processi client e server sono programmati in entrata/uscita.
- su scatole di fascia alta, effetti collaterali NUMA
Ora esaminiamo i risultati.
Confrontando l'implementazione che utilizza i generatori e quella che utilizza le chiamate di funzione, non generano lo stesso numero di roundtrip su Redis. Con il generatore hai semplicemente:
while time.time() - t - expiry < 0:
yield r.get(fpKey)
Quindi 1 andata e ritorno per iterazione. Con la funzione hai:
if r.exists(fpKey):
return r.get(fpKey)
Quindi 2 roundtrip per iterazione. Non c'è da stupirsi che il generatore sia più veloce.
Ovviamente dovresti riutilizzare la stessa connessione Redis per prestazioni ottimali. Non ha senso eseguire un benchmark che si connetta/disconnetta sistematicamente.
Infine, per quanto riguarda la differenza di prestazioni tra le chiamate Redis e le letture dei file, stai semplicemente confrontando una chiamata locale con una remota. Le letture dei file vengono memorizzate nella cache dal file system del sistema operativo, quindi sono operazioni di trasferimento di memoria veloci tra il kernel e Python. Non ci sono I/O del disco coinvolti qui. Con Redis devi pagare il costo dei viaggi di andata e ritorno, quindi è molto più lento.