2011-12-11 3 views
32

R 패키지의 성능 회귀를 감지하는 좋은 워크 플로는 무엇입니까? 이상적으로, 나는 내 코드에서 중요한 성능 회귀를 도입했을 때 나를 경고하는 R CMD check과 통합되는 것을 찾고있다.R의 성능 회피 방지

일반적으로 좋은 워크 플로우는 무엇입니까? 어떤 다른 언어가 좋은 도구를 제공합니까? 최상위 단위 테스트에서 구축 할 수있는 것이거나 일반적으로 별도로 수행되는 것입니까?

+2

까다 롭습니다. 이전과 같은 PC에서 테스트를 실행하지 않아도되므로 안정된 벤치 마크와 관련이 있어야합니다. – Spacedman

+4

* [This method] (http://stackoverflow.com/questions/375913/what -378024 # 378024) * R을 포함하여 모든 언어로 작동합니다. 정확도가있는 시간은 측정하지 않습니다. 그것이하는 일은 시간이 걸리는 코드를 정확하게 지적하고 소요 시간의 대략적인 추정치를 제공합니다. 시간이 지남에 변화가 있거나 그 퍼센트가 크게 증가하면 회귀가 무엇인지 알려줍니다. –

+0

... 높은 비율을 차지하는 항목을 식별하고 수정하면 그 비율이 떨어지기 때문에 전체 시간이 줄어 듭니다. 더 작은 총계의 더 큰 부분을 차지하기 때문에 다른 것의 비율이 올라갑니다. 그것은 예상된다. –

답변

17

매우 까다로운 질문입니다. 일을 빠르게하기 위해 패키지에서 다른 코드를 바꿔 치기 때문에 나는 자주 다루는 질문입니다. 때로는 성능 회귀가 알고리즘 또는 구현의 변경과 함께 발생하지만 사용 된 데이터 구조의 변경으로 인해 발생할 수도 있습니다.

R 패키지에서 성능 회귀를 감지하는 좋은 워크 플로는 무엇입니까?

필자의 경우, 다른 고정 된 데이터 세트로 속도를 높이려는 매우 구체적인 사용 사례가있는 경향이 있습니다. Spacedman이 쓴 것처럼 고정 된 컴퓨팅 시스템을 갖는 것이 중요하지만 이는 거의 불가능합니다. 공유 컴퓨터는 유휴 상태 일지라도 상황을 10-20 % 낮추는 프로세스가있을 수 있습니다.

내 단계 :

  1. 플랫폼 (예를 들어, 하나 또는 몇 기계, 특정 가상 머신 또는 가상 머신 + 특정 인프라, 라 아마존의 EC2 인스턴스 유형)를 표준화.
  2. 속도 테스트에 사용될 데이터 세트를 표준화하십시오.
  3. 최소한의 데이터 변환이 필요한 스크립트 및 고정 중간 데이터 출력 (즉, .rdat 파일로 저장)을 만듭니다. 필자의 초점은 데이터 조작이나 변형이 아닌 일종의 모델링입니다. 이는 모델링 기능에 정확히 동일한 데이터 블록을 제공하고자 함을 의미합니다. 그러나 데이터 변환이 목표 인 경우 사전 변환/조작 된 데이터가 다른 버전의 패키지에 대한 표준 테스트에 가능한 한 가깝도록해야합니다. (비 초점 계산을 표준화하거나 속도를 높이는 데 사용할 수있는 memoization, cacheing 등의 예는 this question을 참조하십시오.) OP34에서 여러 패키지를 참조합니다.
  4. 테스트를 여러 번 반복합니다.
  5. 고정 벤치 마크와 관련하여 결과를 조정합니다 (예 : 선형 회귀를 수행하는 시간, 행렬을 정렬하는 시간 등을 포함 할 수 있습니다. 이는 I/O, 메모리 시스템, 종속 패키지 등으로 인해 인프라에서 "로컬"또는 일시적인 변동을 허용 할 수 있습니다.
  6. 프로파일 링 출력을 가능한 한 격렬하게 조사하십시오 (일부 통찰력은 this question, OP의 도구 참조).

    이상하게도, 내가 코드에서 중요한 성능 회귀를 도입했을 때 알리는 R CMD 검사와 통합되는 것이 이상적입니다.

    불행히도, 나는 이에 대한 대답이 없습니다.

    일반적으로 좋은 워크 플로우는 무엇입니까?

    제게는 일반적인 동적 코드 테스트와 비슷합니다. 출력 (이 경우 실행 시간)이 재현 가능하고 최적이며 투명합니까? 투명성은 전체 시간에 어떤 영향을 미치는지 이해하는 데 있습니다. Mike Dunlavey의 제안이 중요한 부분이지만 라인 프로파일 러를 사용하여 더 나아가고 싶습니다.

    라인 프로파일 러에 대해서는 my previous question을 참조하십시오.이 예제는 Python 및 Matlab의 다른 옵션을 참조합니다. 시계 시간을 검사하는 것이 가장 중요하지만 메모리 할당, 행 실행 횟수 및 호출 스택 깊이를 추적하는 것이 매우 중요합니다.

    다른 유용한 도구가 있습니까?

    거의 모든 다른 언어가 더 나은 도구를 가지고 있습니다. :) Python과 Matlab과 같은 해석 된 언어는 좋은 목적을 위해 적용될 수있는 좋은 도구 인 &을 가지고 있습니다. 동적 분석은 매우 중요하지만 정적 분석은 심각한 문제가있는 곳을 파악하는 데 도움이됩니다. Matlab은 객체 (예 : 벡터, 행렬)가 루프 내부에서 성장하는 경우를보고 할 수있는 훌륭한 정적 분석기를 제공합니다. 동적 분석을 통해서만 이것을 발견하는 것은 끔찍한 일입니다. 이미 이와 같은 것을 발견하기 위해 실행 시간을 낭비했습니다. 실행 컨텍스트가 아주 단순한 경우 (예 : 몇 번의 반복 또는 작은 개체)에는 항상 식별 할 수있는 것은 아닙니다.

    지금까지 언어 무관 한 방법으로, 당신은 볼 수 있습니다 : Cachegrind가

    1. Valgrind의 & cachegrind 등 디스크 I/O, 더러운 버퍼의
    2. 모니터링, RAM의
    3. 모니터링 (도움이,하지만 당신은 단지 RAM 할당 및 RAM 사용에 대한 세부 정보를 많이) 멀티 코어의
    4. 사용을 모니터링 할 수

    최상위 단위 테스트에서 빌드 할 수있는 것이거나 일반적으로 별도로 수행되는 것입니까?

    답변하기가 어렵습니다. 정적 분석의 경우 단위 테스트 이전에 발생할 수 있습니다. 동적 분석을 위해 더 많은 테스트를 추가 할 수 있습니다. 순차 설계 (즉, 실험 설계 프레임 워크)라고 생각하십시오. 실행 비용이 변동에 대한 통계적 허용치 내에서 동일하게 나타나면 추가 테스트가 필요하지 않습니다. 그러나 방법 B가 방법 A보다 평균 실행 비용이 높은 것으로 보인다면,보다 집중적 인 테스트를 수행해야합니다.


업데이트 1 : "패키지의 두 가지 버전의 실행 시간을 비교 몇몇 개는 무엇입니까 : 나는 너무 대담한있을 수 있습니다 경우입니다 내가 포함 권하고 싶습니다 또 다른 질문은, 거기? " 이것은 동일한 알고리즘을 구현하는 두 개의 프로그램이 동일한 중간 객체를 가져야한다고 가정하는 것과 유사합니다. 그건 정확히 사실이 아닙니다. (this question - 내 자신의 질문을 승진시키는 것이 아니라 여기를 참조하십시오.) -이 주제에 대한 여러 가지 질문을 이끌어내는 것 ... :)). 비슷한 방식으로 동일한 코드를 두 번 실행하면 구현 이외의 다른 요인으로 인해 시간이 달라질 수 있습니다.

그래서, 런타임에 영향을 줄 수 있습니다 동일한 실행 인스턴스 내에서 또는 "동일한"인스턴스에서 같은 언어 내에서 또는 언어에서 중 발생할 수있는 몇 개는,,, :

  1. 가비지 수집 - 다른 구현 또는 다른 환경에서 언어가 가비지 콜렉션에 부딪 힐 수 있습니다. 이것은 문맥, 매개 변수, 데이터 세트 등에 매우 의존적 일지라도, 두 가지 실행이 다르게 나타날 수 있습니다. GC- 강박적인 실행은 느려 보일 것입니다.
  2. 디스크, 마더 보드 (예 : L1, L2, L3 캐시) 또는 다른 레벨 (예 : 메모 작성)의 레벨에서 캐시합니다. 종종 첫 번째 처형은 벌금을 지불합니다.
  3. Dynamic voltage scaling -이 사람은 빤다. 문제가있을 때, 이것은 빨리 사라질 수 있기 때문에 발견하기 가장 힘든 짐승 중 하나 일 수 있습니다. 그것은 캐시처럼 보이지만 그렇지 않습니다.
  4. 모르는 작업 우선 순위 관리자.
  5. 하나의 방법은 다중 코어를 사용하거나 코어 또는 CPU간에 작업을 구분하는 방법에 대해 영리한 방법을 사용합니다. 예를 들어, 일부 시나리오에서는 프로세스를 코어에 고정시키는 것이 유용 할 수 있습니다. R 패키지의 한 실행은이 점에서 운이 좋을 수 있습니다. 다른 패키지는 매우 똑똑 할 수 있습니다 ...
  6. 사용되지 않은 변수, 과도한 데이터 전송, 더티 캐시, 버퍼 플러시되지 않은 버퍼 등 ... 목록이 계속됩니다.

결과는 다음과 같습니다. 이상적인 결과는 주문 효과로 인해 생성 된 임의성에 따라 예상 값의 차이를 테스트해야합니다. 음, 꽤 간단합니다. 실험 디자인으로 돌아가십시오. :)

실행 시간의 경험적 차이가 "예상 된"차이와 다른 경우 추가 시스템 및 실행 모니터링을 활성화하여 우리가 파란색이 될 때까지 실험을 다시 실행할 필요가 없도록하는 것이 좋습니다. 면전에 대고.

10

여기에서 무엇을 할 수있는 유일한 방법은 몇 가지 가정을하는 것입니다. 그래서 우리는 변경되지 않은 기계를 가정하거나 "재 교정"이 필요합니다.

그런 다음 단위 테스트 프레임 워크를 사용하고 또 다른 테스트 기준으로 'X 단위로 완료해야합니다'를 처리해야합니다. 즉,

stopifnot(timingOf(someExpression) < savedValue plus fudge) 

과 같은 식으로 처리하십시오. 따라서 주어진 타이밍에 사전 타이밍을 연관시켜야합니다. 기존의 세 가지 단위 테스트 패키지 중 하나와 동일한 테스트 비교를 사용할 수도 있습니다.

해들리가 처리 할 수 ​​없었던 것은 없었습니다. 그래서 저는 우리가 새로운 패키지를 기대할 수 있다고 생각합니다. timr 다음 학술적 휴식 시간이 지나면 :). 물론 이것은 "알 수없는"기계 (CRAN이 패키지를 테스트한다고 생각 함)에 대한 참조 점이 없거나 새로운 기계에서 자동으로 승인하기 위해 퍼지 요소가 "11로 가야"하기 때문에 선택 사항이어야합니다 .

+0

또는 아마도 testthat 확장? expect_that (foo (x), takes_less_than (bar (y)))? – Spacedman

+0

'bar (y)'는'foo (x)'의 이전 시간과 약간의 허용 오차/퍼지 측정을 얻는 함수입니까? 혹시. –

+0

이 연결되어 있는지 확실하지 않지만'svUnit'은 유닛 테스트에서'타이밍 '정보를 캡처하여 로그에보고합니다. – Ramnath

4

R-devel 피드에서 발표 된 최근 변경 사항은이를 해결하는 데 큰 도움이 될 수 있습니다. R-(STABLE) UTILITIES

'R CMD 검사'IN

변경 사항 체크의 다양한 부분에 대한 보고서 타이밍을 선택적으로 할 수 이것은 '작성 R 확장'에 설명 된 환경 변수에 의해 제어됩니다.

는 테스트를 실행 소요 된 전체 시간을 확인하고 이전 값과 비교 될 수 http://developer.r-project.org/blosxom.cgi/R-devel/2011/12/13#n2011-12-13

를 참조하십시오. 물론 새로운 테스트를 추가하면 시간이 늘어나지 만 수동으로 수행하더라도 극적인 성능 저하가 여전히 나타날 수 있습니다.

이것은 개별 테스트 스위트 내에서 타이밍 지원만큼 정교하지는 않지만 특정 테스트 스위트에 의존하지도 않습니다.