2016-08-04 36 views
3

Ich habe Schwierigkeiten mit der Zugriffszeit auf das erste Element einer data.frame. Die Zugriffszeiten scheinen von der Größe des data.frame abhängig zu sein. Kann jemand diese Abhängigkeit beseitigen?Warum hängt die Zugriffszeit für das erste Element eines data.frames von seinen Dimensionen ab?

Dies ist ein Codebeispiel, das ich ausgeführt habe. Es ordnet „TME“, die die Zeiten speichert erforderlich, um das erste Element einer data.frame von lengthi*1000 zu setzen, wo i geht von 1 bis 500. Im Wesentlichen I zuzuteilen länger data.frames in Schritten von 1000 und stellen das erste Element auf Null. Kurz: data.frames Die Zugriffszeiten liegen weit unter der Messbarkeit, bei langen Arrays erreichen sie mehrere Sekunden.

tme <- (1:500) 
for (j in 1:500){ 
    i <- j*1000 
    vec <- (1:(i*1000)) 
    print(i) 
    now <- Sys.time() 
    vec[1] <- 0 
    tme[j] <- Sys.time()-now 
} 
tme_vec_first <- tme 
+3

Huh beobachtet? Ich sehe keinen data.frame irgendwo in der Nähe dieses Codes. – Frank

Antwort

6

Ich glaube nicht, dass die Zunahme der Zeit mit Zugriffszeit zusammenhängt, sondern eher durch das Erstellen von Kopien. Bei jeder dieser Zuordnungen wird eine Kopie des Vektors erstellt. Sie können dies mit tracemem testen.

# initialize vector (10 zeros) 
tracemem({vec <- integer(10)}) 

[1] "< 0000000011D48720>"

# assign value to 7th position 
tracemem({vec[7] <- 6L}) 

tracemem [0x0000000011d48720 -> 0x00000000111a02b0]:
[1] "< 0000000012E25468>"

Wenn der Vektor größer wird, nimmt die Zeit, die mit dem Kopiervorgang verbunden ist, zu.


Ferner ist zu beachten, dass eine ganze Zahl vec <- (1:(i*1000)) Vektor ist, und schaltet sich vec[1] <- 0 VEC in ein Doppelvektor, der in etwa verdoppelt die Größe des Vektors im Speicher.

Zuerst erstellen wir den Ganzzahlvektor und überprüfen seine Größe und seinen Typ.

# start over with similar syntax to question 
tracemem({vec <- 1:10}) 

[1] "< 0000000011E55508>"

# Kontrollgröße object.size (VEC)

88 Bytes

# check type 
typeof(vec) 
Jetzt

[1] "integer"

, zuordnen 0 bis 7. Position und Wiederprüfung Größe und Typ. 0 scheint derselbe Wert zu sein wie der anfänglich vorhandene Wert, ist aber tatsächlich eher ein Double als eine ganze Zahl.

# assign value 
tracemem({vec[7] <- 0}) 

tracemem [0x0000000011e55508 -> 0x0000000]:
tracemem [0x0000000-> 0x0000000013394740]:
[1] "< 00000000130EBA60>"

# check size 
object.size(vec) 

168 Bytes

# check type 
typeof(vec) 

[1] "double"

Hinweis hier, dass es zwei separate Kopie Anweisungen. Meine Vermutung ist, dass die erste die Kopie ist, um den Vektor von Integer in Double zu konvertieren, und die zweite ist die Zuweisung.

Um den Vektor als Ganzzahlvektor zu behalten, verwenden Sie stattdessen vec[1] <- 0L, da "L" R mitteilt, dass eine ganze Zahl gewünscht wird.


Beachten Sie, dass dieses Kopierverhalten tracemem sowohl mit Rstudio und Rgui in MS R offen 3.2.5 mit Windows 7.

+1

Ich dachte, R optimierte diese Kopien weg. Scheinbar nicht. –

+0

In welcher Version von R werden diese Kopien erstellt? Im Allgemeinen (und wenn "vec" nicht von einem anderen Objekt referenziert wird) sollte 'vec' nicht kopiert werden, wenn ihm eine" ganze Zahl "zugewiesen wird, und nur einmal kopiert werden (erzwungen), wenn ihm ein" double "zugewiesen wird. Oh, außer es ist in Rstudio? Ich denke, ich erinnere mich an etwas ähnliches wieder auf SO –

+1

Ich benutze 3.2.3 MS Revo Open im Moment. Ich war ziemlich überrascht über die Kopien, da auch keine Kopien mein Verständnis waren. Ich werde versuchen, daran zu erinnern, dies mit 3.3.1 gepatcht in ein paar Stunden zu überprüfen, aber ich vermute jetzt, dass ich das gleiche Ergebnis bekommen werde. – lmo