2012-10-07 18 views
24

मान लीजिए मैं आर में एक सूची बना सकते हैं और इसे करने के लिए संलग्न के रूप में निम्नानुसार है:प्रतिलिपि में आर परिणाम में एक सूची में शामिल है?

x = list(10) 
x[[2]] = 20 

x = list(10) 
x = list(10, 20) 

को यह बराबर है? मैं विशेष विवरण के साथ इतना अनुभवी नहीं हूं कि कैसे स्मृति स्मृति में सूचियों को सूचीबद्ध करता है, लेकिन मेरी सीमित समझ यह है कि यह प्रति-खुश होने लगता है; मेरे लिए आदर्श क्या होगा कि पहला विकल्प अनिवार्य रूप से स्मृति में एक और सूची बनाने में शामिल नहीं है, लेकिन केवल लागू मूल्य के लिए स्मृति में एक नई जगह को अलग करने के परिणामस्वरूप। अनिवार्य रूप से, अगर मेरे पास एक बड़ी सूची है, तो मैं नहीं चाहता कि आर इसकी एक और प्रतिलिपि बनाये, अगर मैं इसे कुछ जोड़ना चाहता हूं।

यदि मैं जो व्यवहार चाहता हूं वह यहां नहीं दिया गया है, तो क्या वांछित प्रभाव प्राप्त करने का कोई और तरीका है?

+4

शायद '? Tracemem' का उपयोग किया जाएगा? – Chase

+1

और 'पहले और बाद में (निरीक्षण) (एक्स))' पहले और बाद में। –

उत्तर

15

मुझे पूरा विश्वास है कि उत्तर "नहीं" है।

Rprof(tmp <- tempfile(), memory.profiling = TRUE) 

x <- list() 
for (i in 1:100) x[[i]] <- runif(10000) 

Rprof() 
summaryRprof(tmp, memory = "stats") 
unlink(tmp) 

उत्पादन:

# index: runif 
#  vsize.small max.vsize.small  vsize.large max.vsize.large 
#   76411   381781   424523   1504387 
#   nodes  max.nodes  duplications tot.duplications 
#   2725878   13583136    0    0 
#   samples 
#    5 

प्रासंगिक हिस्सा होने duplications = 0 मैं दोहरी जांच के लिए निम्न कोड का इस्तेमाल किया।

+3

मुझे नहीं लगता कि आपकी तर्क जरूरी है: डुप्लिकेशंस का आर में विशेष अर्थ है, और तकनीकी रूप से, एक वेक्टर की लंबाई बढ़ाने के दौरान एक प्रतिलिपि बनाता है, यह एक नकल नहीं है। आर-सहायता पर यह धागा देखें: http://r.789695.n4.nabble.com/Understanding-tracemem-td4636321.html – hadley

4

स्वीकार किए गए फ्लोडल का जवाब, लेकिन चेस की नोक अच्छी थी इसलिए मैंने पुष्टि की कि मेरे पास tracemem() का उपयोग करने के अपने सुझाव का उपयोग करके वांछित व्यवहार है।

x = list(10) 
tracemem(x[[1]]) 
# [1] "<0x2d03c78>" 
x = list(10, 20) 
tracemem(x[[1]]) 
# [1] "<0x2d07ff8>" 

तो पहली विधि दिखाई देता है:

x = list(10) 
tracemem(x[[1]]) 
# [1] "<0x2d03fa8>" #(likely different on each machine) 
x[[2]] = 20 
tracemem(x[[1]]) 
# [1] "<0x2d03fa8>" 

और यहाँ दूसरे उदाहरण है, जहाँ हम दो सूचियां बनाने के से परिणाम है: यहाँ पहला उदाहरण है, जहां हम सिर्फ सूची में संलग्न है वांछित व्यवहार दें।

10

मैथ्यू Dowle के जवाब here और अधिक स्मृति क्षमता के पीछे तर्क <-, [<-, [[<- और अन्य आधार R परिचालन (names आदि)

[[<- द्वारा पर्दे के पीछे नकल को रोकने के लिए कई x की पूरी कॉपी जाएगा । नीचे

x <- list(20) 
tracemem(x) 
#[1] "<0x2b0e2790>" 
x[[2]] <- 20 
# tracemem[0x2b0e2790 -> 0x2adb7798]: 

उदाहरण देखें आपका दूसरा मामला

x <- list(10,20) 

वास्तव में मूल x जोड़कर नहीं है, लेकिन एक वस्तु है कि एक साथ जोड़ दिया मूल्य के साथ मूल x होने के साथ x की जगह।

+0

(+1), दूसरा मामला संलग्न नहीं है, या कुछ ऐसा उदाहरण है जो मैं था प्रस्तावित, बल्कि कुछ ऐसा उदाहरण जो मैं नहीं चाहता कि आर दृश्यों के पीछे हो। – guy

+0

आह, मैंने आपके प्रश्न को गलत तरीके से पढ़ा है, यह पहली बार मुझे पढ़ता था क्योंकि आप पूछ रहे थे कि 'x <- सूची (10,20)' बराबर थी (स्मृति के संदर्भ में) 'x <- सूची (10); एक्स [[2]] <- 20'। रीडिंग पर मैं देखता हूं कि यह उससे अधिक नीच था। – mnel

+0

हां लेकिन उस लिंक किए गए उत्तर में 'x'' data.frame' था। इस प्रश्न में 'x' एक 'सूची' है। 'सूची' के व्यवहार की प्रतिलिपि अलग हो सकती है। ध्यान दें कि कोई '[<-। List' विधि नहीं है लेकिन एक' [<-। Data.frame' है। जांचने के लिए 'अनन्त (निरीक्षण (एक्स)) 'का प्रयोग करें। –

8

किसी सूची को संशोधित करने या संशोधित करने में मेरी सहायता करने के लिए एक गहरी प्रतिलिपि या उथली प्रतिलिपि बनाता है, मैंने एक छोटा प्रयोग स्थापित किया है।एक सूची को संशोधित करने के एक गहरी प्रतिलिपि बनाता है, तो यह धीमी होना चाहिए जब आप एक सूची है कि एक बड़ी वस्तु शामिल संशोधित कर रहे हैं एक सूची है कि एक छोटी सी वस्तु शामिल की तुलना में:

z1 <- list(runif(1e7)) 
z2 <- list(1:10) 

system.time({ 
    for(i in 1:1e4) z1[1 + i] <- 1L 
}) 
# user system elapsed 
# 0.283 0.034 0.317 
system.time({ 
    for(i in 1:1e4) z2[1 + i] <- 1L 
}) 
# user system elapsed 
# 0.284 0.034 0.319 

अपने कंप्यूटर पर समय मूल रूप से थे समान, यह सुझाव देते हुए कि एक सूची की प्रतिलिपि बनाना एक उथली प्रतिलिपि बनाता है, पॉइंटर्स को मौजूदा डेटा संरचनाओं में कॉपी करता है।

+7

'आंतरिक (निरीक्षण (एक्स)) 'बताने का एक और ठोस तरीका है। यह देखना चाहते हैं कि लंबे वेक्टर का हेक्स पता बदल गया है या नहीं। –

+0

@MatthewDowle नाइस, धन्यवाद। – hadley

संबंधित मुद्दे