2011-09-13 2 views
1

소수점 두 자리가있는 POSIX 변수의 경우 successor() 함수가 심각한 성능 손실을 보임을 알게되었습니다. 게다가 for 루프는 좋은 r-style *이 아닐 수도 있습니다. POSIX의 두 자리수가 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 [내가 + 1, Y0 = Y [i]를, Y1 = Y [I + 1 ]). 어쨌든 두번 값을 저장하는 것이 낭비되는 것 같기 때문에 후임자/전임자를 다룰 수있는 또 다른 방법이 있어야합니다. 하지만 나는 프로그래머가 아니다.

답변

3

이다 결과가 같은 것을 나타내는

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

타이밍 및 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를 추가, u 클래스 POSIXlt 동안은

하여 예에서
> 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