2012-05-18 6 views
20

タイトルのとおり。なぜ潤滑機能がそれほど遅いのですか?as.POSIXctと比べて、なぜRubridateの機能が遅いのですか?

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

私は経験が豊富だが、私の推測では、Rubridate関数は多くのことを「裏口」で処理するように設計されているということです。あなたに合理的な結果を与えてください。[バックグラウンド文書](https://github.com/hadley/lubridate)を読んで、これらの感情をエコーし​​ます。それが遅いかどうかにかかわらず、わかりませんが...同様に、 'plyr'ファミリは便宜のために書かれており、特定の状況下では基本関数と比較してパフォーマンスがあまり良くないかもしれませんが、使いやすいです! – Chase

+0

@ RJ-実際にあなたの質問には違いを示すコードがあります。 'system.time'を使って測定することができます。 – Tommy

+0

Noted。すぐに投稿します。 – JackeJR

答えて

38

同じ理由から車はriding on top of rocketsと比べて遅いです。追加された使いやすさと安全性は、ロケットよりも車の速度をはるかに遅くしますが、爆発する可能性は低く、車の始動、操縦、ブレーキングが容易です。しかし、適切な状況(例えば、私は月に着く必要がある)では、ロケットは仕事のための適切なツールです。誰かが屋根に縛られたロケットを持った車を発明したら、何かを持っているだろう。

(あなたbechmarksからの方法で、私はlubridateは、これらのようなはるかに遅いが、ミリ秒単位であるということであることを言わないだろう)dmyがやっている、あなたはスピードのための違いを見ることができます何を見ているとスタート:

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_datenum_to_datemake_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-tingexpand-ing.grid-spaste-ingifelse-ingunname-ingなどに加えて、全ロッタエラーチェックゲーミングオン(ZEPソングで再生)を得ました。だから、私たちがここにあるのは、素晴らしい構文的砂糖です。 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は、この機能はまだあるサイモンUrbanekによって fasttimeパッケージから移植され、内蔵の非常に高速なPOSIXパーサを持っています。 オプションで、オプションで有効にすることができます(lubridate.fasttime = TRUE)。Lubridateは自動的にPOSIX文字列を検出し、デフォルトのstrptimeユーティリティの代わりに高速の パーサを使用します。"

関連する問題