2013-05-18 12 views
41

Ho lavorato su alcuni progetti che mi hanno richiesto di eseguire molte sottotitoli di elenchi e mentre creavo il codice di profilo mi sono reso conto che l'oggetto [["nomeHere"]] si avvicinava agli elenchi di subsetting di solito era più veloce dell'oggetto $ nameHere approccio.

Per fare un esempio se creiamo una lista con i componenti nominati:

a.long.list <- as.list(rep(1:1000)) 
names(a.long.list) <- paste0("something",1:1000) 

Perché è questo:

system.time (
for (i in 1:10000) { 
    a.long.list[["something997"]] 
} 
) 


user system elapsed 
0.15 0.00 0.16 

più veloce di questo:

system.time (
    for (i in 1:10000) { 
     a.long.list$something997 
    } 
) 

user system elapsed 
0.23 0.00 0.23 

La mia domanda è semplicemente se questo comportamento è vero universalmente e dovrei evitare il sottoinsieme $ ove possibile o fare il c più efficiente la scelta dipende da altri fattori?

+9

+1. Sospetto che sia legato alla corrispondenza parziale con il segno '$'. Supponiamo di avere 'my_list <- list (" a "= 1," asso "= 2)'. Se provi 'my_list $ ac' ottiene' asso', ma se provi 'my_list [[" ac "]]', non trova nulla. – Frank

+1

Non rispondendo alla tua domanda, ma se le prestazioni fossero un problema, allora preferiresti scrivere una query di ricerca vettorizzata <- sample (names (a.long.list), 1000); a.long.list [query] 'per giocare bene con il tuo altro codice vettoriale. –

+5

non escludendo la teoria della corrispondenza parziale, ma quello che spero che una risposta completa includa è perché aggiungendo 'exact = FALSE' a' [['nell'esempio dell'OP non diminuisce la performance. – flodel

risposta

9

La funzione [[ esegue prima tutti gli elementi cercando la corrispondenza esatta, quindi tenta di eseguire una corrispondenza parziale. La funzione $ prova entrambe le corrispondenze esatte e parziali su ciascun elemento a turno. Se si esegue:

system.time (
    for (i in 1:10000) { 
    a.long.list[["something9973", exact=FALSE]] 
    } 
) 

vale a dire, si esegue una corrispondenza parziale dove non c'è corrispondenza esatta, vi accorgerete che $ è di fatto sempre in modo leggermente più veloce.

+0

Penso che questo risponda alla domanda chiarissima di Flodel sul perché l'aggiunta esatta = FALSE non riduca le prestazioni.Ad ogni modo ora sono convinto che nei contesti di programmazione in cui la velocità conta sarà meglio usare [[a meno che non ci sia un'alta probabilità di aver bisogno di un partial matching (che più spesso crea bug nei miei programmi piuttosto che risolvere i problemi). –

Problemi correlati