2010-12-06 19 views
19

ठीक है, हम आर में डबल कॉलन ऑपरेटर से परिचित हैं। जब भी मैं कुछ फ़ंक्शन लिखने वाला हूं, तो मैं require(<pkgname>) का उपयोग करता हूं, लेकिन मैं हमेशा :: का उपयोग करने के बारे में सोच रहा था। कस्टम कार्यों में require का उपयोग library की तुलना में बेहतर अभ्यास है, जो त्रुटि देता है यदि आप न के बराबर पैकेज का एक नाम प्रदान require रिटर्न चेतावनी और FALSE, library के विपरीत, के बाद से।आर लेखन शैली - बनाम ::

दूसरी ओर, :: ऑपरेटर पैकेज से परिवर्तनीय हो जाता है, जबकि require पूरे पैकेज को लोड करता है (कम से कम मुझे उम्मीद है), तो मेरे दिमाग में गति अंतर पहले आया। ::require से तेज़ होना चाहिए।

और मुझे लगता है कि जाँच करने के लिए कुछ विश्लेषण किया था - मैं क्रमशः require और :: साथ दो साधारण कार्यों कि foreign पैकेज से read.systat समारोह लोड, लिखा है, इसलिए Iris.syd डाटासेट आयात कि foreign पैकेज, दोहराया कार्यों 1000 बार साथ जहाजों प्रत्येक (जो लापरवाही से मनमाना था), और ... कुछ संख्याओं को तोड़ दिया।

अजीब (या नहीं) मैं, उपयोगकर्ता सीपीयू और बीता हुआ समय के मामले में काफी अंतर पाया, जबकि सिस्टम CPU के मामले में कोई महत्वपूर्ण मतभेद थे। और अभी तक और अधिक अजीब निष्कर्ष: :: वास्तव में धीमा है! :: के लिए प्रलेखन बहुत ही बदमाश है, और केवल स्रोतों को देखकर यह स्पष्ट है कि :: बेहतर प्रदर्शन करना चाहिए!

#!/usr/local/bin/r 

## with require 
fn1 <- function() { 
    require(foreign) 
    read.systat("Iris.syd", to.data.frame=TRUE) 
} 

## times 
n <- 1e3 

sink("require.txt") 
print(t(replicate(n, system.time(fn1())))) 
sink() 

डबल पेट

#!/usr/local/bin/r 

## with :: 
fn2 <- function() { 
    foreign::read.systat("Iris.syd", to.data.frame=TRUE) 
} 

## times 
n <- 1e3 


sink("double_colon.txt") 
print(t(replicate(n, system.time(fn2())))) 
sink() 

ले लो सीएसवी डेटा here आवश्यकता होती है। कुछ आंकड़े:

user CPU:  W = 475366 p-value = 0.04738 MRr = 975.866 MRc = 1025.134 
system CPU: W = 503312.5 p-value = 0.7305 MRr = 1003.8125 MRc = 997.1875 
elapsed time: W = 403299.5 p-value < 2.2e-16 MRr = 903.7995 MRc = 1097.2005 

एमआरआर require के लिए मतलब रैंक है, एमआरसी :: के लिए ibid। मैंने यहां कुछ गलत किया होगा। यह सिर्फ कोई समझ नहीं आता है ... :: के लिए निष्पादन समय तेजी से लगता है !!! मैंने कुछ खराब कर दिया है, आपको उस विकल्प को त्यागना नहीं चाहिए ...

ठीक है ... मैंने यह देखने के लिए अपना समय बर्बाद कर दिया है कि कुछ अंतर है, और मैंने पूरी तरह से बेकार विश्लेषण किया है, इसलिए , वापस सवाल का:

"क्यों एक require:: से अधिक पसंद करते हैं चाहिए जब एक समारोह लिख?"

=)

+0

यह एक पैकेज में स्टैंडअलोन कार्य या कार्यों के लिए है? – hadley

+0

इसके अलावा, आपको आमतौर पर प्रत्येक स्क्रिप्ट कॉल में, एक बार अपनी स्क्रिप्ट के शीर्ष पर() की आवश्यकता होती है। – hadley

+1

यह स्टैंडअलोन फ़ंक्शंस के लिए है। मैं एक वेब अनुप्रयोग विकसित कर रहा हूं, और चूंकि रैपैच प्रत्येक HTTP अनुरोध पर नया आर सत्र शुरू करता है, इसलिए मैं अनावश्यक सर्वर लोड से बचने की कोशिश कर रहा हूं। यह उदाहरण अनुचित है - एक बार जब आप फ़ाइल आयात करते हैं, तो काम पूरा हो जाता है, लेकिन एजेक्स कॉल के गुच्छा के साथ एक इंटरैक्टिव वेबपैप में, यह काफी अक्षम हो सकता है। – aL3xa

उत्तर

12

"क्यों एक ::से अधिक की आवश्यकता होती है को प्राथमिकता देनी चाहिएएक समारोह लिखते समय? "

मैं आमतौर पर अच्छा सही/गलत वापसी मुझे पैकेज कोड में हो रही से पहले सामने उपलब्ध होने की संभावना नहीं के साथ सौदा देता है कि मूल्य की वजह से require पसंद करते हैं। अपने विश्लेषण के माध्यम से आधा रास्ते के बजाय जितनी जल्दी हो सके क्रैश करें।

मैं केवल :: का उपयोग करता हूं, जब मुझे यह सुनिश्चित करने की ज़रूरत होती है कि मैं फ़ंक्शन के सही संस्करण का उपयोग कर रहा हूं, नाम का मुखौटा करने वाले किसी अन्य पैकेज से संस्करण नहीं।

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

मुझे लगता है कि आप आलसी लोड हो रहा है जो the first page of its manual के अनुसार foreign पैकेज द्वारा प्रयोग किया जाता है के प्रभाव की अनदेखी हो सकती है। अनिवार्य रूप से, आलसी लोडिंग का उपयोग करने वाले पैकेज ऑब्जेक्ट्स को लोड करने से रोकते हैं, जैसे फंक्शंस, जब तक ऑब्जेक्ट पहली बार नहीं कहा जाता है। तो आपका तर्क है कि ":: आवश्यकता से तेज़ होना चाहिए" foreign के रूप में जरूरी नहीं है कि यह आपकी सभी सामग्री को स्मृति में लोड नहीं कर रहा है जब आप require के साथ संलग्न करते हैं। आलसी लोडिंग पर पूरी जानकारी के लिए, Prof. Ripley's article आरएन्यूज़, वॉल्यूम 4, अंक 2 में देखें।

+0

आप बहुत सही हैं ... और यह पैकेज-निर्भर समस्या हो सकती है। ओह, और संदर्भ के लिए धन्यवाद। – aL3xa

6

चूंकि पैकेज लोड करने का समय लगभग हमेशा छोटा होता है, यह पता लगाने के लिए कि आप छह महीने के कोड को कैसे समझते हैं पहले के बारे में था, इस मामले में स्पष्टता के लिए कोडिंग सबसे महत्वपूर्ण बात है।

स्क्रिप्ट के लिए, शुरुआत में require या library पर कॉल करने से आपको पता चलता है कि आपको कौन से पैकेज सीधे चाहिए।

इसी तरह, एक समारोह के शुरू में बुला require (या ggplot2 में Hmisc या try_require में requirePackage की तरह एक आवरण) दिखा रहा है कि आपको लगता है कि पैकेज का उपयोग करने की आवश्यकता का सबसे स्पष्ट तरीका है।

::, परिस्थितियां हैं जब आपको संकुल – तुलना करें, उदा के बीच संघर्ष का नामकरण किया है के लिए आरक्षित किया जाना चाहिए

Hmisc::is.discrete 

और

plyr::is.discrete 
संबंधित मुद्दे