글꼴 잠금 성능 최적화


13

고정 글꼴 잠금 일치의 변형을 수행하고 싶습니다. 이름 목록으로 시작하는 함수 정의가 있으며 함수 본문 내에서 해당 이름을 강조 표시하고 싶습니다.

이 작업을 수행하고 jit-lock-register를 사용하여 jit-lock 함수로 등록했지만 성능이 상당히 떨어지고 큰 파일에서 스크롤링이 지연됩니다.

  • 성능을 어떻게 측정 할 수 있습니까? 큰 파일에서 함수를 호출하는 시간 (float-time 전후 또는 elp 사용)을 사용하면 성능이 크게 달라지며 0.65 ~ 12 초가 걸립니다. 글꼴 잠금 성능을 벤치마킹하는 권장 방법이 있습니까?
  • font-lock-keywords에 정의 된 앵커 매처와 jit-lock-register를 통해 함수를 추가하는 경우 성능에 차이가 있습니까?

편집 : 성능의 가변성이 가비지 수집과 관련이있는 것 같습니다. 가비지 수집이 실행될 때까지 각 호출마다 내 jit-lock 함수의 호출이 연속적으로 느려져 다시 빨라집니다.


첫 번째 항목의 경우 프로파일 러를 사용해보십시오.
Malabarba

프로파일 러를 사용하여 시간이 걸리는 코드 부분을 볼 수도 있지만 성능이 일관성이 없기 때문에 변경 사항이 개선되었는지 여부를 말하기가 어렵습니다.
Joakim Hårsman

테스트 할 수있는 코드가 있습니까? 그것은 우리에게 많은 도움이 될 것입니다.
PythonNut

1
프로파일 링 또는 마이크로 최적화에 관한 것이 아니지만 그 자체로 : font-lock-studio 패키지는 글꼴 잠금 성능을 이해하는 데 유용한 또 다른 도구 라는 것을 알았 습니다. 다른 인터랙티브 스테핑 디버거가 도움을 줄 수있는 것과 같은 방식으로 도움이 될 수 있습니다. 실행 경로가 예상 한 것이 아니라는 것이 주요 성능 문제입니다.
Greg Hendershott

font-lock-studio에 대한 팁을 보내 주셔서 감사합니다. jit-lock-functions에는 도움이되지 않지만 다른 모든 것에는 도움이됩니다.
Joakim Hårsman

답변:


8

매우 다양한 성능이 가비지 수집과 관련이있는 것으로 나타났습니다. 가비지 수집이 실행될 때까지 함수를 호출 할 때마다 속도가 느려집니다. 스톡 이맥스를 사용하면 gc가 몇 초마다 실행되었지만 시작 시간을 개선하여 gc-cons-threshold를 20MB로 설정하고 gc가 훨씬 더 자주 실행되지 않아 벤치 마크가 발생하는 init.el에 줄이 생겼습니다. 몇 분 후에 gc가 실행될 때까지 느리고 느린 타이밍을보고하면 시간이 급감하고 다시 빠릅니다.

기본 gc-cons-threshhold로 되 돌린 후 벤치마킹이 쉬워졌습니다.

그런 다음 내장 프로파일 러 ( M-x profiler-start)를 사용하여 메모리를 프로파일 링 하고 syntax-ppss를 호출하면 가장 많은 할당이 발생한다는 것을 알았습니다. 따라서 구문 -ppss를 호출하는 최적화가 덜 자주 허용되는 성능을 달성했습니다.

jit-lock-mode를 사용하여 (jit-lock-register를 통해 기능 추가) 다중 행 글꼴 잠금을 안정적으로 작동시키는 가장 쉬운 방법 인 것 같습니다. 이것이 제가 선택한 방법입니다.

편집 : 성능이 여전히 매우 큰 버퍼에서 충분하지 않다는 것을 알게 된 후 내장 Emacs 프로파일 러 ( M-x profiler-start)를 사용하여 CPU 사용 및 할당을 최적화하는 데 많은 시간을 보냈습니다 . 그러나 Emacs는 매우 큰 버퍼를 빠르게 스크롤 할 때 더듬 거리고 멈추게됩니다. 내가 등록한 jit-lock 기능 jit-lock-register을 제거하면 말더듬과 정지가 제거되지만 프로파일 링을 통해 jit-lock 기능이 약 8ms 내에 완료되는 것으로 나타났습니다. jit-lock-register일반 글꼴 잠금 키워드 매처를 호출 하거나 대신 사용하여 문제를 해결했습니다.

TLDR :이 작업은 느리고 말더듬이됩니다.

(defun my-font-lock-function (start end)
"Set faces for font-lock between START and END.")

(jit-lock-register 'my-font-lock-function)

이 작업은 빠르고 빠르지 않습니다.

(defun my-font-lock-function (start end)
"Set faces for font-lock between START and END.")

(defun my-font-lock-matcher (limit)
    (my-font-lock-function (point) limit)
   nil)

(setq font-lock-defaults
  (list 
     ...
    ;; Note that the face specified here doesn't matter since
    ;; my-font-lock-matcher always returns nil and sets the face on
    ;; its own.
    `(my-font-lock-matcher (1 font-lock-keyword-face nil))))

사용한 코드를 공유 할 수 있습니까? 귀하의 솔루션은 다른 사람이 동일한 것을 달성하는 데 도움이 될 수 있습니다.
Manuel Uberti

나는 실제로 특정 코드를 사용하지 않았으며 구문 -ppss를 덜 호출했습니다. : 현재 문제의 코드를 확인하실 수 있습니다 bitbucket.org/harsman/dyalog-mode/src/... 에 봐 dyalog-fontify-locals.
Joakim Hårsman

나는 dyalog-fontify-locals-matcher이어야 my-font-lock-matcher하고 그 중 하나는 end이어야한다 limit. 어쨌든, 정말로 흥미로운 발견!
Lindydancer

@Lindydancer : 예 감사합니다. 결정된.
Joakim Hårsman

1
Re : gc-cons-threshold, 시작 시간을 향상시키기 위해 순전히 내부 값을 엉망으로 emacs-startup-hook만드는 경우 나중에 복원하는 데 사용 하는 것이 좋습니다 .
phils
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.