2012-11-16 2 views
6

replicate() 함수가 R에서 작동하는 방식과 for 루프를 사용하는 것이 상대적으로 얼마나 효율적인지 누구든지 알고 있습니까?for 루프와 Replicate()?

예를 들어, 사이의 효율 차이가 ...

means <- replicate(100000, mean(rnorm(50))) 

그리고 ...

means <- c() 
for(i in 1:100000) { 
    means <- c(means, mean(rnorm(50))) 
} 

(I 약간 이상 떨어져 무언가를 입력 한 수 있습니다,하지만 당신은 아이디어를 얻을.)

답변

14

코드를 벤치 마크하고 경험적으로 대답을 얻을 수 있습니다. 벡터를 미리 할당하여 증가하는 벡터 문제를 우회하는 두 번째 for 루프 풍미를 추가했습니다. relative 열 찾고

repl_function = function(no_rep) means <- replicate(no_rep, mean(rnorm(50))) 
for_loop = function(no_rep) { 
    means <- c() 
    for(i in 1:no_rep) { 
     means <- c(means, mean(rnorm(50))) 
    } 
    means 
} 
for_loop_prealloc = function(no_rep) { 
    means <- vector(mode = "numeric", length = no_rep) 
    for(i in 1:no_rep) { 
     means[i] <- mean(rnorm(50)) 
    } 
    means 
} 

no_loops = 50e3 
benchmark(repl_function(no_loops), 
      for_loop(no_loops), 
      for_loop_prealloc(no_loops), 
      replications = 3) 

         test replications elapsed relative user.self sys.self 
2   for_loop(no_loops)   3 18.886 6.274 17.803 0.894       
3 for_loop_prealloc(no_loops)   3 3.209 1.066  3.189 0.000       
1  repl_function(no_loops)   3 3.010 1.000  2.997 0.000       
    user.child sys.child 
2   0   0                     
3   0   0                     
1   0   0 

상기 사전 할당은 비 - 루프 6.2 배 느리다. 그러나 사전 할당 된 for 루프는 replicate만큼 빠릅니다.

8

replicatesapply의 래퍼이며, 그 자체는 lapply의 래퍼입니다. lapply은 궁극적으로 C로 작성되고 인터프리터가 아닌 최적화 된 방식으로 루핑을 수행하는 .Internal 함수입니다. 효율적인 메모리 관리가 주된 이점입니다. 특히 위에 제시 한 매우 비효율적 인 벡터 재배 방법과 비교하면 더욱 그렇습니다.

+1

미리 할당 된 for 루프는 '복제'와 마찬가지로 빠릅니다. 코드의 주요 부분이 R에서 소비 되었기 때문이라고 생각합니다. 예를 들어, 'mean'을 중심으로 전체 루프를 다시 구현합니다. C++은 일을 상당히 빠르게 할 것입니다. 내 대답 벤치 마크를 참조하십시오. –

1

나는 매우 혼란스러운 replicate과 다른 경험이 있습니다. 위에 언급 된 이유 때문에 나는 for과 비교했을 때 을 사용했을 때 내 R이 충돌하고 노트북이 멈추는 경우가 종종 있었고, for 루프를 능가하는 C 작성 함수를 기대했습니다. 아래의 기능을 수행하는 경우 예를 들어, for 루프가 명확하게 빠르다, for 루프가 10 복제로보다 빠른 replicate

system.time(for (i in 1:10) runif(1e7)) 
# user system elapsed 
# 3.340 0.218 3.558 

system.time(replicate(10, runif(1e7))) 
# user system elapsed 
# 4.622 0.484 5.109 

그렇다고 볼 수 있습니다. 당신이 100 복제를 위해 그것을 반복한다면 당신은 비슷한 결과를 얻습니다. 그래서 어떤 사람이 그 에 비해 실제 권한을 보여주는 예제와 함께 올 수 있다면 궁금해.

추신 : 또한 runif(1e7)에 대한 함수를 만들었지 만 비교에서 차이가 없습니다. 기본적으로 나는 replicate의 장점을 보여주는 예제와 함께하지 못했습니다.

1

벡터화가 주요 차이점입니다. 나는이 점을 설명하기 위해 트레이닝 할 것이다. R은 고수준의 컴퓨터 언어입니다. 그것은 당신을 위해 많은 기본적인 컴퓨터 작업을 처리합니다. 당신이

x <- 2.0 

를 쓸 때 당신은

  • "2.0"부동 소수점 숫자입니다 컴퓨터를 말할 필요가 없습니다;
  • "x"는 숫자 형식 데이터를 저장해야합니다.
  • "5"를 넣으려면 메모리에 위치를 찾아야합니다.
  • 메모리의 특정 위치에 대한 포인터로 "x"를 등록해야합니다.

R 이러한 것들을 단독으로 계산합니다.

그러나 이러한 편안한 문제 때문에 가격이 책정됩니다. 저급 언어보다 느립니다.

C 또는 FORTRAN에서이 "테스트 if"의 상당 부분은 프로그램 실행 중에 컴파일 단계에서 수행됩니다. 이 코드는 작성된 후, 실행되기 전에 2 진 컴퓨터 언어 (0/1)로 변환됩니다. 이를 통해 컴파일러는 컴퓨터가 해석 할 수있는 최적의 방법으로 이진 시스템 코드를 구성 할 수 있습니다.

R의 벡터화와 무슨 관련이 있습니까? 음, 많은 R 함수는 실제로 C, C++ 및 FORTRAN과 같이 컴파일 된 언어로 작성되며 작은 R "래퍼"를가집니다. 이것은 당신의 접근 방식의 차이입니다. for 루프는 머신이 데이터에 대해 수행해야하는 작업을 test if에 추가하여 느리게 만듭니다.

관련 문제