को समझने के लिए यहाँ क्या हो रहा है, तो आप, आर में वस्तुओं हर वस्तु, कोई डेटा के साथ भी एक वस्तु के साथ जुड़े स्मृति भूमि के ऊपर के बारे में थोड़ा जानने की जरूरत के 40 बाइट्स है इसके साथ जुड़े डेटा:
x0 <- numeric()
object.size(x0)
# 40 bytes
यह स्मृति वस्तु के प्रकार के स्टोर करने के लिए (के रूप में typeof()
द्वारा दिया) प्रयोग किया जाता है, और अन्य मेटाडाटा स्मृति प्रबंधन के लिए की जरूरत है।
इस ओवरहेड को अनदेखा करने के बाद, आप उम्मीद कर सकते हैं कि वेक्टर की स्मृति उपयोग वेक्टर की लंबाई के समान है।
sizes <- sapply(0:50, function(n) object.size(seq_len(n)))
plot(c(0, 50), c(0, max(sizes)), xlab = "Length", ylab = "Bytes",
type = "n")
abline(h = 40, col = "grey80")
abline(h = 40 + 128, col = "grey80")
abline(a = 40, b = 4, col = "grey90", lwd = 4)
lines(sizes, type = "s")
यह स्मृति के उपयोग की तरह दिखता है मोटे तौर पर वेक्टर की लंबाई के लिए आनुपातिक है, लेकिन वहाँ 168 बाइट्स और छोटे discontinuities पर एक बड़ा अलगाव हर है: चलो भूखंडों के एक जोड़े के साथ कि बाहर की जाँच करते हैं कुछ कदम। बड़ी असंतोष इसलिए है क्योंकि आर में वैक्टर के लिए दो स्टोरेज पूल हैं: ओएस द्वारा प्रबंधित छोटे वैक्टर, और बड़े वैक्टर, यह एक प्रदर्शन अनुकूलन है क्योंकि स्मृति की बहुत सारी मात्रा आवंटित करना महंगा है)।
sizes - 40
# [1] 0 8 8 16 16 32 32 32 32 48 48 48 48 64 64 64 64 128 128 128 128
# [22] 128 128 128 128 128 128 128 128 128 128 128 128 136 136 144 144 152 152 160 160 168
# [43] 168 176 176 184 184 192 192 200 200
128 करने के लिए 64 से कदम बड़ा कारण बनता है: छोटे वैक्टर केवल 8, 16, 32, 48, 64 या 128 बाइट्स लंबे, एक बार हम 40 बाइट ओवरहेड को दूर जो हो सकता है, हम देखते हैं ठीक है
# diff(sizes)
# [1] 8 0 8 0 16 0 0 0 16 0 0 0 16 0 0 0 64 0 0 0 0 0 0 0 0 0 0 0
# [29] 0 0 0 0 8 0 8 0 8 0 8 0 8 0 8 0 8 0 8 0 8 0
: कदम है, तो एक बार हम बड़े वेक्टर पूल में पार कर लिया है, वैक्टर 8 बाइट (स्मृति एक निश्चित आकार की इकाइयों में आता है, और आर आधे से एक इकाई के लिए नहीं पूछ सकते हैं) की मात्रा में आवंटित किए जाते हैं
तो यह व्यवहार मैट्रिस के साथ आप जो देखते हैं उससे मेल खाता है? ठीक है, पहले हम एक मैट्रिक्स के साथ जुड़े भूमि के ऊपर से देखने की जरूरत है:
xv <- numeric()
xm <- matrix(xv)
object.size(xm)
# 200 bytes
object.size(xm) - object.size(xv)
# 160 bytes
तो एक मैट्रिक्स भंडारण की एक अतिरिक्त 160 बाइट्स की जरूरत है एक सदिश की तुलना में। 160 बाइट क्यों?क्योंकि एक मैट्रिक्स दो पूर्णांकों युक्त एक dim
विशेषता है यह, और विशेषताओं एक pairlist
(list()
के एक पुराने संस्करण) में जमा हो जाती है:
object.size(pairlist(dims = c(1L, 1L)))
# 160 bytes
हम पिछले साजिश वैक्टर के बजाय मैट्रिक्स का उपयोग कर, और वृद्धि को फिर से आकर्षित हैं y- अक्ष 160 द्वारा पर सभी स्थिरांक, आप देख सकते अलगाव बड़ा वेक्टर पूल करने के लिए छोटे वेक्टर पूल से कूद करने के लिए बिल्कुल मेल खाती है:
msizes <- sapply(0:50, function(n) object.size(as.matrix(seq_len(n))))
plot(c(0, 50), c(160, max(msizes)), xlab = "Length", ylab = "Bytes",
type = "n")
abline(h = 40 + 160, col = "grey80")
abline(h = 40 + 160 + 128, col = "grey80")
abline(a = 40 + 160, b = 4, col = "grey90", lwd = 4)
lines(msizes, type = "s")
गु matrices से संबंधित नहीं है (जो आर वैसे भी वेक्टर हैं)। 'आकार <- प्रतिनिधि (NA_integer_, 100) देखें; के लिए (मैं 1: 100 में) आकार [i] <- object.size (प्रतिनिधि (1, i)); साजिश (आकार) '। – Roland
चरित्र 'एम <- मैट्रिक्स (' ए ', 2, i)' और पूर्णांक 'एम <- मैट्रिक्स (1 एल, 2, i)' और 'm <- मैट्रिक्स (TRUE, 2, i) पर एक नज़र डालें - या अधिक रोचक रूप से @ रोलैंड ने सुझाव दिया (चरित्र, पूर्णांक और तार्किक वैक्टर के लिए)। – mnel
@ साइमन ओ 101 हैडली ने इसे चैट में समझाया। मुझे आशा है कि उसे उचित उत्तर लिखने का समय मिल जाएगा। उदाहरण के लिए, [इस अनुभाग को आर-एक्सट्स में पढ़ें] (http://cran.r-project.org/doc/manuals/R-exts.html#Profiling-R-code-for-memory-use)। – Roland