2012-05-18 15 views
20

शीर्षक के रूप में जाना जाता है। लुब्र्रिडेट इतना धीमा क्यों काम करता है?as.POSIXct की तुलना में लुब्र्रिडेट फ़ंक्शन इतनी धीमी क्यों होती है?

library(lubridate) 
library(microbenchmark) 

Dates <- sample(c(dates = format(seq(ISOdate(2010,1,1), by='day', length=365), format='%d-%m-%Y')), 50000, replace = TRUE) 

microbenchmark(as.POSIXct(Dates, format = "%d-%b-%Y %H:%M:%S", tz = "GMT"), times = 100) 
microbenchmark(dmy(Dates, tz ="GMT"), times = 100) 

Unit: milliseconds 
expr               min   lq   median  uq   max 
1 as.POSIXct(Dates, format = "%d-%b-%Y %H:%M:%S", tz = "GMT") 103.1902 104.3247 108.675  109.2632 149.871 
2 dmy(Dates, tz = "GMT")          184.4871 194.1504 197.8422 214.3771 268.4911 
+4

मैं कोई है जो अधिक का अनुभव है झंकार दूँगा, लेकिन मेरा अनुमान है कि lubridate कार्यों के लिए बहुत कुछ को संभालने के लिए तैयार कर रहे हैं कि" दृश्य "यह इनपुट के और अधिक जाँच/पुनरीक्षण कर प्रयास करने के लिए है जिसका अर्थ है पीछे और आपको उचित परिणाम देते हैं। [पृष्ठभूमि दस्तावेज़] (https://github.com/hadley/lubridate) को पढ़ना इन भावनाओं को उजागर करता है। चाहे वह धीमेपन से संबंधित हो या नहीं, मुझे यकीन नहीं है ... लेकिन वह होगा मेरा अनुमान है। इसी तरह, 'प्लीर' परिवार सुविधा के लिए भी लिखा गया है और कुछ परिस्थितियों में आधार कार्यों की तुलना में अपेक्षाकृत खराब प्रदर्शन कर सकता है ... लेकिन इसका उपयोग करना आसान है! – Chase

+0

@ आरजे- यदि आपके पास वास्तविक था तो यह बेहतर होगा आपके प्रश्न में कोड जो अंतर दिखाता है। 'system.time' को मापने के लिए उपयोग किया जा सकता है। – Tommy

+0

नोट किया गया। इसे जल्द ही पोस्ट कर देगा। – JackeJR

उत्तर

38

इसी कारण कारों के लिए riding on top of rockets की तुलना में धीमी गति से कर रहे हैं। उपयोग और सुरक्षा की अतिरिक्त आसानी से रॉकेट की तुलना में कारों को धीमा कर दिया जाता है लेकिन आपको उड़ाया जाने की संभावना कम होती है और कार शुरू करना, स्टीयर करना और ब्रेक करना आसान होता है। हालांकि, सही स्थिति में (उदाहरण के लिए, मुझे चाँद तक पहुंचने की जरूरत है) रॉकेट नौकरी के लिए सही उपकरण है। अब अगर किसी ने छत पर चिपके हुए रॉकेट वाले एक कार का आविष्कार किया तो हमारे पास कुछ होगा।

क्या dmy को देख कर रहा है और आप गति के लिए अंतर देखेंगे (अपने bechmarks से जिस तरह से मैं यह नहीं कहूंगा lubridate है कि इतना इन के रूप में धीमी मिलीसेकेंड में कर रहे हैं) के साथ प्रारंभ:

dmy कमांड लाइन में #type इस और आपको मिलता है:

>dmy 
function (..., quiet = FALSE, tz = "UTC") 
{ 
    dates <- unlist(list(...)) 
    parse_date(num_to_date(dates), make_format("dmy"), quiet = quiet, 
     tz = tz) 
} 
<environment: namespace:lubridate> 

तुरंत मैं parse_date और num_to_date और make_format देखते हैं। एक आश्चर्य करता है कि ये सभी लोग क्या हैं। चलो देखते हैं:

parse_date

> parse_date 
function (x, formats, quiet = FALSE, seps = find_separator(x), 
    tz = "UTC") 
{ 
    fmt <- guess_format(head(x, 100), formats, seps, quiet) 
    parsed <- as.POSIXct(strptime(x, fmt, tz = tz)) 
    if (length(x) > 2 & !quiet) 
     message("Using date format ", fmt, ".") 
    failed <- sum(is.na(parsed)) - sum(is.na(x)) 
    if (failed > 0) { 
     message(failed, " failed to parse.") 
    } 
    parsed 
} 
<environment: namespace:lubridate> 

num_to_date

> getAnywhere(num_to_date) 
A single object matching ‘num_to_date’ was found 
It was found in the following places 
    namespace:lubridate 
with value 

function (x) 
{ 
    if (is.numeric(x)) { 
     x <- as.character(x) 
     x <- paste(ifelse(nchar(x)%%2 == 1, "0", ""), x, sep = "") 
    } 
    x 
} 
<environment: namespace:lubridate> 

make_format

> getAnywhere(make_format) 
A single object matching ‘make_format’ was found 
It was found in the following places 
    namespace:lubridate 
with value 

function (order) 
{ 
    order <- strsplit(order, "")[[1]] 
    formats <- list(d = "%d", m = c("%m", "%b"), y = c("%y", 
     "%Y"))[order] 
    grid <- expand.grid(formats, KEEP.OUT.ATTRS = FALSE, stringsAsFactors = FALSE) 
    lapply(1:nrow(grid), function(i) unname(unlist(grid[i, ]))) 
} 
<environment: namespace:lubridate> 

वाह हमें strsplit-ting, expand-ing.grid-s, paste-ing, ifelse-ing, unname-ing इत्यादि के साथ-साथ एक पूर्ण लॉटा त्रुटि पर जा रहा है (ज़ेप गीत पर खेलें)। तो हमारे पास यहाँ कुछ अच्छी वाक्य रचनात्मक चीनी है। Mmmmm स्वादिष्ट लेकिन यह एक कीमत, गति के साथ आता है।

तुलना करें कि को as.POSIXct:

getAnywhere(as.POSIXct) #tells us to use methods to see the business 
methods('as.POSIXct') #tells us all the business 
as.POSIXct.date   #what I believe your code is using (I don't use dates though) 

वहाँ एक बहुत अधिक आंतरिक कोडिंग और कम त्रुटि तो तुम मुझे कम करना चाहते हैं और कर पूछने के लिए है as.POSICct साथ चल रहा है की जाँच के सुरक्षा या गति और शक्ति? नौकरी पर निर्भर करता है।

+6

+1 महान जवाब। साथ ही, क्या आपने देखा कि 'parse_date()' स्वयं 'as.POSIXct() 'को कॉल करता है? तो अंत में, 'dmy() 'कार में हुड के नीचे एक' as.POSIXct()' इंजन है। –

+2

मुझे लगता है कि यह वास्तव में एक वर्ण तर्क को संभालने के लिए 'as.POSIXct.default' का उपयोग कर रहा है (' Dates' एक वर्ण वेक्टर है)। –

+0

जिन्होंने कभी भी इस प्रतिक्रिया को कम किया है, यह अजीब लगता है क्योंकि 24 अन्य लोगों ने इसे उपयोगी पाया। क्या आप अपनी पसंद में कुछ अंतर्दृष्टि दे सकते हैं? –

8

@ टायलर का जवाब सही है। यहाँ कुछ और अधिक जानकारी तेजी lubridate बनाने पर एक टिप सहित है - मदद फ़ाइल से:।

"Lubridate इनबिल्ट बहुत तेजी से POSIX पार्सर, साइमन Urbanek द्वारा fasttime पैकेज से मोड़ा है यह कार्यक्षमता के रूप में अभी तक है वैकल्पिक और विकल्पों के साथ सक्रिय किया जा सकता है (lubridate.fasttime = TRUE)। लुब्रिडेट स्वचालित रूप से POSIX स्ट्रिंग का पता लगाएगा और डिफ़ॉल्ट स्ट्रिपटाइम उपयोगिता के बजाय पार्सर का उपयोग करेगा।"