2011-09-13 10 views
1

小数点以下2桁のPOSIX変数の場合、次の関数successor()は大幅なパフォーマンスの低下を示しています。それ以外にも、forループは良いr-style *ではないかもしれません。私のシステムでは、小数点なしのPOSIXよりも2小数点以下のPOSIXが約30倍(20000段)遅いことに驚きました。小数点を含むPOSIXはベクトルを文字として格納するよりもさらに遅くなります。小数点以下を伴うPOSIX変数のパフォーマンスがR

successor()関数のためにパフォーマンスが低下しますか?それとも、Rで時間/日付変数を文字として格納し、実際に必要なときに変換することができるのかという一般的なアドバイスはありますか?

successor <- function(z) { 
y<-as.vector(z) 
for(i in 1:NROW(z)) { 
y[i] <- if(i == NROW(z)) NA else z[i+1] 
} 
return(y) 
} 

u<-rep(strptime("15.01.2010 10:21:52.85",format="%d.%m.%Y %H:%M:%OS"),20000) # fragments of seconds stored 
v<-seq(c(ISOdate(2011,09,12)),by="min", length.out=20000) # no fragments of seconds saved 
u.posix.time.small<-system.time(successor(u[1:1000])) 
u.char.time.small<-system.time(successor(as.character(u[1:1000]))) 
u.posix.time.big<-system.time(successor(u[1:20000])) 
u.char.time.big<-system.time(successor(as.character(u[1:20000]))) 

v.posix.time.small<-system.time(successor(v[1:1000])) 
v.char.time.small<-system.time(successor(as.character(v[1:1000]))) 
v.posix.time.big<-system.time(successor(v[1:20000])) 
v.char.time.big<-system.time(successor(as.character(v[1:20000]))) 
rbind(u.posix.time.small,u.posix.time.big,u.char.time.small, u.char.time.big,v.posix.time.small, v.posix.time.big, v.char.time.small,v.char.time.big)[,1:3] 

セグメント(X0の=を使用する場合、私は先行/ sucessor物に出くわした* X [i]は、X1 = xで[I + 1]、Y0 = Y [i]は、Y1 = Y [I + 1 ])をプロットします。とにかく、値を2回保存することは無駄に思えるので、後継者/先任者に対処する別の方法がなければならないと思います。しかし、私はプログラマだけのユーザーではない。

答えて

3

あなたの例では、uはクラスPOSIXlt中ですvはクラスPOSIXctです。 uPOSIXctに変換するとタイミングが非常に似ています。

POSIXltオブジェクトはベクターのリストとして格納されるため効率が悪いですが、POSIXctオブジェクトは単一の数値ベクトルとして格納されます。

> u <- as.POSIXct(u) 
> u.posix.time.small<-system.time(successor(u[1:1000])) 
> u.char.time.small<-system.time(successor(as.character(u[1:1000]))) 
> u.posix.time.big<-system.time(successor(u[1:20000])) 
> u.char.time.big<-system.time(successor(as.character(u[1:20000]))) 
> rbind(u.posix.time.small,u.posix.time.big,u.char.time.small, u.char.time.big, 
+ v.posix.time.small, v.posix.time.big, v.char.time.small,v.char.time.big)[,1:3] 
        user.self sys.self elapsed 
u.posix.time.small  0.04  0.00 0.04 
u.posix.time.big  1.91  0.01 1.92 
u.char.time.small  0.01  0.00 0.02 
u.char.time.big   0.29  0.02 0.32 
v.posix.time.small  0.05  0.00 0.04 
v.posix.time.big  1.43  0.00 1.44 
v.char.time.small  0.02  0.00 0.01 
v.char.time.big   0.32  0.00 0.32 
+0

私は、何かが間違っていなければならないことを知っていました。そのため、一般的なパフォーマンスの問題が説明されています。だから、私は次回POSIXctに日付オブジェクトを格納するために私を連れて行きます。ありがとう。 – Sebastian

5

問題はループであり、データ型ではありません。 Rでは、常にループを使用するの前に関数をベクトル化します。

実行時間が実質的にかからない後継関数の別の定式化です。それは単にベクトルの最初の要素をドロップしてから最後の要素として、NAを追加します。

successor2 <- function(x){ c(x[-1], NA) } 

タイミングと結果が同じであることを示す:

> system.time(XX <- successor2(as.numeric(v))) 
    user system elapsed 
     0  0  0 
> system.time(YY <- successor(v)) 
    user system elapsed 
    5.98 0.00 7.97 
> all.equal(XX, YY) 
[1] TRUE 
+0

ありがとう、これは本当に効果的です。私はそのように考えることを学びます。 – Sebastian

関連する問題