2013-06-03 5 views
3

저는 지금 당장 R을 배웠고, 제 작 같은 벡터화 작업에 많은 조언을했습니다. 프로그래머이기 때문에 왜 더 빨리/더 빨리 할 수 ​​있을지에 관심이 있습니다. 예 :왜 벡터화가 더 빠릅니까

n = 10^7 
# populate with random nos 
v=runif(n) 
system.time({vv<-v*v; m<-mean(vv)}); m 
system.time({for(i in 1:length(v)) { vv[i]<-v[i]*v[i] }; m<-mean(vv)}); m 

이것은

user system elapsed 
    0.04 0.01 0.07 
[1] 0.3332091 

    user system elapsed 
    36.68 0.02 36.69 
[1] 0.3332091 

고려해야 할 가장 눈에 띄는 것은 그림과 같이, 오히려 해석 코드보다 ++ 우리는, 네이티브 코드를 실행하는, 즉 기계 코드가 C 또는 C에서 컴파일 된 것입니다했다 두 가지 예 (3 정도의 순서대로) 사이의 사용자 시간의 엄청난 차이 때문입니다. 하지만 다른 일이 있습니까? 예를 들어 R은 다음을 수행합니다.

  • 교묘 한 네이티브 데이터 구조. 희소 한 벡터 또는 행렬을 저장하는 영리한 방법을 사용하여 필요시 곱셈 만 수행 할 수 있습니까?

  • 지연 평가. 행렬 곱셈에서 필요할 때까지 셀을 평가하지 마십시오.

  • 병렬 처리.

  • 다른 것.

내가

(경과 0.09 년경)

# populate with random nos 
v<-runif(n) 
system.time({m<-v%*%v/n}); m 
# populate with runs of 1 followed by 99 0s 
v <-rep(rep(c(1,rep(0,99)),n/100)) 
system.time({m<-v%*%v/n}); m 
# populate with 0s 
v <-rep(0,n) 
system.time({m<-v%*%v/n}); m 

그러나 시간에 유의 한 차이가 없었다 차이 벡터 내용으로 내적을하고 시도 약간의 스파 스 벡터 최적화가있을 수 있습니다 여부를 테스트하려면 (Matlab에 대한 비슷한 질문 : Why does vectorized code run faster than for loops in MATLAB?)

답변

9

고려해야 할 가장 확실한 것은 우리가 네이티브 코드를 실행하는 것입니다, C 또는 C++에서 컴파일 즉 기계 코드보다는 대부분의 코드

을 해석했다. 다른 중요한 요소는 R 코드가 디자인 패러다임에서 기능적이기 때문에 기능 (시도)에 부작용이 없다는 것입니다. 즉, 일부는 그렇지만 (전부는 아닐 수도 있음) R 은 이것에 대해 효율적으로 수행합니다. for 루프에서 [<-을 호출하는 인스턴스는 전체 객체를 복사해야합니다. 은 느려질 수 있습니다.

작은 참고 사항 : R은 sparse 매트릭스 구조를 효율적으로 처리하기 위해 광범위한 기능을 가지고 있지만 "기본값"이 아닙니다.

+0

감사합니다. 저는 루프에서 함수가 의미하는 바를 따르지 않았습니다. 간단한 예제 나 참조를 제공 할 수 있습니까? (일반적으로 R의 기능적 측면이 사용자의 요점 보기 - 지금까지 내가 한 모든 일은 꽤 절차 적이었다.) – TooTone

+0

@TooTone'x <- 1:10; tracemem (x); x [5] <- 1'은 아마도 가장 간단한 예일 것입니다. – joran

+0

그것은 미묘합니다. 나는 그 일이 일어나고 있는지 전혀 몰랐다. (토론방이있다. (http://r.789695.n4.nabble.com/Why-is-vector-assignment-in-R-recreates-the-entire-vector- td2403402.html). R은 대개이 복사본을 최적화하여 다른 사람이 더 자세히 살펴보고자 할 때 사용합니다. 나는 몇 가지 테스트를 수행했으며,'for' 루프를 사용하여 코드에서'vv'는'i == 1 '일 때 한 번 복사되지만 성능에는 영향을 미치지 않습니다. – TooTone

4

병렬 처리와 관련하여, out of the-box R은 어떤 parall 처리. 물론 parallel 패키지가 내장되어 있지만 코드를 사용하여 코드를 수정해야합니다. mclapply은 병렬 처리를 사용합니다. 선형 대수학을 blas의 특수 버전을 사용하여 병렬로 계산할 수있는 옵션이 있지만 작동시키기는 어렵지 않지만 R에서는 표준 적으로 사용하지 않습니다.

+0

감사합니다. 병렬 처리가 Revolution Analytics R (사랑하거나 싫어하는)이 사업을 시도하는 한 가지 방법이라고 생각합니다. – TooTone

7

두 예제 모두에서 해석 된 코드와 네이티브 코드를 모두 실행하고 있습니다.차이점은 두 번째로는 R 레벨에서 루프를 수행하여 더 많은 함수 호출이 필요하며 그 결과 모든 C 코드가 호출되어야한다는 것입니다. 첫 번째 예제에서 루프는 컴파일 된 코드 내에서 발생하므로 R은 해석하기가 훨씬 적고 R 코드 호출이 훨씬 적으며 컴파일 된 코드를 호출하는 횟수가 훨씬 적습니다.