elisp 코드의 성능을 어떻게 측정합니까? 소요 시간을 측정 할 수있는 도구 / 외부 패키지는 무엇입니까?
총 시간 외에도 기능별 소요 시간을 보여주는 프로필을 볼 수 있습니까? 메모리 사용량도 프로파일 링 할 수 있습니까?
답변
기준
가장 간단한 옵션은 내장 benchmark
패키지입니다. 사용법은 매우 간단합니다.
(benchmark 100 (form (to be evaluated)))
자동로드되므로 필요하지 않아도됩니다.
프로파일 링
벤치 마크는 전체 테스트에 적합하지만 성능 문제가있는 경우 어떤 기능이 문제를 일으키는 지 알려주지 않습니다. 이를 위해 (내장) 프로파일 러가 있습니다.
- 로 시작하십시오
M-x profiler-start
. - 시간이 많이 걸리는 작업을 수행하십시오.
- 로 보고서를 받으십시오
M-x profiler-report
.
탐색 가능한 함수 호출 트리가있는 버퍼로 이동해야합니다.
답변
@Malabara의 답변 외에도 사용자 정의 with-timer
매크로를 사용하여 코드의 다양한 부분 (예 : init.el
파일) 을 영구적으로 계측 하는 경향이 있습니다 .
차이점은 benchmark
계측하는 특정 코드 비트의 성능을 연구 할 수 있지만 with-timer
항상 코드의 각 계측 된 부분에 소요되는 시간 (충분히 큰 부분에 대한 오버 헤드없이)을 제공한다는 점입니다. 어떤 부분을 더 조사해야하는지
(defmacro with-timer (title &rest forms)
"Run the given FORMS, counting the elapsed time.
A message including the given TITLE and the corresponding elapsed
time is displayed."
(declare (indent 1))
(let ((nowvar (make-symbol "now"))
(body `(progn ,@forms)))
`(let ((,nowvar (current-time)))
(message "%s..." ,title)
(prog1 ,body
(let ((elapsed
(float-time (time-subtract (current-time) ,nowvar))))
(message "%s... done (%.3fs)" ,title elapsed))))))
사용 예 :
(with-timer "Doing things"
(form (to (be evaluated))))
*Messages*
버퍼에 다음과 같은 출력이 나타납니다 .
Doing things... done (0.047s)
Jon Wiegley의 use-package-with-elapsed-timer
뛰어난 use-package
확장 기능 에서 큰 영향을 받았다는 점을 언급해야 합니다.
답변
@Malabarba의 답변 외에도을 사용 하여 코드 의 컴파일 된 실행 시간을 측정 할 수 있습니다 benchmark-run-compiled
. 이 메트릭은 종종 다음 을 제공 하는 해석 된 실행 시간 보다 훨씬 관련성이 M-x benchmark
있습니다.
ELISP> (benchmark-run (cl-loop for i below (* 1000 1000) sum i))
(0.79330082 6 0.2081620540000002)
ELISP> (benchmark-run-compiled (cl-loop for i below (* 1000 1000) sum i))
(0.047896284 0 0.0)
세 개의 숫자는 총 경과 시간, GC 실행 횟수 및 GC에 소요 된 시간입니다.
답변
벤치마킹은 숫자를 얻는 것뿐만 아니라 결과 분석을 기반으로 결정을 내리는 것입니다.
MELPA 에는 benchstat.el 패키지 가 있으며 benchstat 프로그램이 제공 하는 기능을 얻는 데 사용할 수 있습니다 .
비교 X
속성 벤치마킹을 구현하여 에 대한 성능 속성 을 검사 합니다 Y
.
Benchstat 함수는 benchmark-run-compiled
정보를 수집 할뿐만 아니라 해석 형식을 쉽게 읽을 수 있는 래퍼 로 볼 수 있습니다 . 다음을 포함합니다 :
X
와 사이의 경과 시간 델타Y
- 평균 평균 시간
- 할당 금액
매우 간단한 사용법 예 :
(require 'benchstat)
;; Decide how much repetitions is needed.
;; This is the same as `benchmark-run-compiled` REPETITIONS argument.
(defconst repetitions 1000000)
;; Collect old code profile.
(benchstat-run :old repetitions (list 1 2))
;; Collect new code profile.
(benchstat-run :new repetitions (cons 1 2))
;; Display the results.
;; Can be run interactively by `M-x benchstat-compare'.
(benchstat-compare)
은 benchstat-compare
임시 버퍼에 결과를 렌더링 :
name old time/op new time/op delta
Emacs 44.2ms ± 6% 25.0ms ±15% -43.38% (p=0.000 n=10+10)
name old allocs/op new allocs/op delta
Emacs 23.0 ± 0% 11.4 ± 5% -50.43% (p=0.000 n=10+10)
benchstat
그래도 프로그램 바이너리 가 필요 합니다. Go 프로그래밍 언어를 사용한 경우 시스템에 이미 언어가있는 것 같습니다. 그렇지 않으면 소스에서 컴파일하는 옵션이 있습니다.
linux / amd64 용 사전 컴파일 된 바이너리는 github release page 에서 찾을 수 있습니다 .