2008-09-17 15 views
5

मेरे पास फ़ंक्शन के अंदर एक लूप के अंदर एक फ़ंक्शन है। आंतरिक कार्य स्मृति में डेटा के एक बड़े वेक्टर को प्राप्त करता है और स्टोर करता है (एक वैश्विक चर के रूप में ... मैं "आर" का उपयोग कर रहा हूं जो "एस-प्लस" जैसा है)। लूप डेटा प्राप्त करने के लिए डेटा की एक लंबी सूची के माध्यम से loops। बाहरी कार्य प्रक्रिया शुरू करता है और प्राप्त किए जाने वाले डेटासेट की सूची में गुजरता है।बदतर पाप: दुष्प्रभाव या भारी वस्तुओं को पारित करना?

for (dataset in list_of_datasets) { 
    for (datachunk in dataset) { 
    <process datachunk> 
    <store result? as vector? where?> 
    } 
} 

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

क्या उत्तर बदल जाएगा यदि मैं स्मृति में बजाए डेटाबेस में डेटा वैक्टर संग्रहीत कर रहा था? आदर्श रूप में, मैं समाप्ति से पहले संसाधित सभी सूचनाओं को खोए बिना फ़ंक्शन को समाप्त करने में सक्षम होना चाहता हूं (या नेटवर्क टाइमआउट के कारण यह विफल हो गया है)।

+2

मैं इस पोस्ट को संपादित करने की सलाह देते हैं तो यह आसान है तुम क्या करने –

+0

हाँ कृपया स्यूडोकोड जोड़ने की कोशिश कर रहे हैं क्या देखने के लिए कुछ संक्षिप्त स्यूडोकोड शामिल करने के लिए , यह जानना असंभव है कि आपका क्या मतलब है। जब आप कहते हैं "प्रक्रिया ... और परिणाम संग्रहित करें", तो क्या आपका मतलब है "सटीक उसी स्ट्रिंग को स्टोर करें", या वेक्टर (इनट्स, संदर्भ संदर्भ), या क्या? क्या आप इसे कुछ विशाल डेटाफ्रेम/सरणी/मैट्रिक्स में रिकॉर्ड के रूप में संग्रहीत कर रहे हैं? हमें पंक्तियों, स्तंभों, फ़ाइल, खंड और वेक्टर आकारों और आपकी कार्यशील स्मृति की संख्या का कुछ विचार दें? – smci

उत्तर

-1

भाषा/संकलक का उपयोग किए बिना निश्चित रूप से कहना मुश्किल है। हालांकि, अगर आप उस ऑब्जेक्ट को केवल पॉइंटर/संदर्भ पास कर सकते हैं जिसे आप बना रहे हैं, तो ऑब्जेक्ट का आकार फ़ंक्शन कॉल की गति से कुछ लेना देना नहीं है। सड़क के नीचे इस डेटा को जोड़ना एक अलग कहानी हो सकती है।

+1

वह जिस भाषा का उपयोग कर रहा है वह है: http://r-project.org/ – Allen

10

वैश्विक चर के बजाय बाहरी फ़ंक्शन में चर का उपयोग करें। यह आपको दोनों दृष्टिकोणों में से सर्वश्रेष्ठ बनाता है: आप वैश्विक स्थिति को म्यूट नहीं कर रहे हैं, और आप डेटा का एक बड़ा हिस्सा कॉपी नहीं कर रहे हैं। अगर आपको जल्दी से बाहर निकलना है, तो आंशिक परिणाम वापस करें।

0

तीसरा दृष्टिकोण:

(http://cran.r-project.org/doc/manuals/R-intro.html#Scope आर के मैनुअल में "स्कोप" अनुभाग देखें): आंतरिक समारोह बड़े सरणी, जो लूप के अंदर अगले स्टेटमेंट तो dereferences और दुकानों जहाँ भी यह आवश्यक है के लिए एक संदर्भ रिटर्न (आदर्श रूप से एक एकल सूचक स्टोर के साथ और पूरे सरणी को memcopy करने के द्वारा नहीं)।

यह दोनों दुष्प्रभावों और बड़े डेटास्ट्रक्चर के पारित होने से छुटकारा पाता है।

4

यह स्मृति उपयोग में बहुत अंतर नहीं करेगा, इसलिए आप कोड को साफ भी कर सकते हैं।

चूंकि आर में चर के लिए प्रति-संशोधित है, वैश्विक वस्तु को संशोधित करने के लिए समान मूल्य प्रभावों में कुछ गुजरने के समान स्मृति प्रभाव होंगे।

यदि आप डेटाबेस में आउटपुट को संग्रहीत करते हैं (या यहां तक ​​कि एक फ़ाइल में) तो आपके पास मेमोरी उपयोग समस्याएं नहीं होंगी, और डेटा अंत में उपलब्ध होने के बजाय, वृद्धि के रूप में उपलब्ध होगा। चाहे यह डेटाबेस के साथ तेज़ी से हो, मुख्य रूप से आप कितनी मेमोरी का उपयोग कर रहे हैं इस पर निर्भर करता है: कमी है कचरा संग्रह डिस्क पर लिखने की लागत के लिए भुगतान करने जा रहा है।

आर में समय और मेमोरी प्रोफाइलर दोनों हैं, इसलिए आप अनुभव कर सकते हैं कि प्रभाव क्या हैं।

1

मुझे यकीन नहीं है कि मैं सवाल समझता हूं, लेकिन मेरे पास कुछ समाधान हैं।

  1. फ़ंक्शन के अंदर, वैक्टर की एक सूची बनाएं और उसे वापस करें।

  2. फ़ंक्शन के अंदर, वातावरण बनाएं और उसके अंदर के सभी वैक्टरों को स्टोर करें। बस सुनिश्चित करें कि आप त्रुटियों के मामले में पर्यावरण वापस कर दें।

आर में

:

help(environment) 

# You might do something like this: 

outer <- function(datasets) { 
    # create the return environment 
    ret.env <- new.env() 
    for(set in dataset) { 
    tmp <- inner(set) 
    # check for errors however you like here. You might have inner return a list, and 
    # have the list contain an error component 
    assign(set, tmp, envir=ret.env) 
    } 
    return(ret.env) 
} 

#The inner function might be defined like this 

inner <- function(dataset) { 
    # I don't know what you are doing here, but lets pretend you are reading a data file 
    # that is named by dataset 
    filedata <- read.table(dataset, header=T) 
    return(filedata) 
} 

लीफ

6

अपने नुथ याद रखें। "समयपूर्व अनुकूलन सभी प्रोग्रामिंग बुराई की जड़ है।"

साइड इफेक्ट फ्री संस्करण आज़माएं। देखें कि यह आपके प्रदर्शन लक्ष्यों को पूरा करता है या नहीं। यदि यह करता है, तो बढ़िया, आपको पहली जगह में कोई समस्या नहीं है; यदि ऐसा नहीं होता है, तो साइड इफेक्ट्स का उपयोग करें, और अगले प्रोग्रामर के लिए नोट करें कि आपके हाथ को मजबूर किया गया था।

1

FYI करें, यहाँ एक पूर्ण नमूना खिलौना समाधान है कि दुष्प्रभाव से बचा जाता है है:

outerfunc <- function(names) { 
    templist <- list() 
    for (aname in names) { 
    templist[[aname]] <- innerfunc(aname) 
    } 
    templist 
} 

innerfunc <- function(aname) { 
    retval <- NULL 
    if ("one" %in% aname) retval <- c(1) 
    if ("two" %in% aname) retval <- c(1,2) 
    if ("three" %in% aname) retval <- c(1,2,3) 
    retval 
} 

names <- c("one","two","three") 

name_vals <- outerfunc(names) 

for (name in names) assign(name, name_vals[[name]]) 
संबंधित मुद्दे