Yazı tipi kilidi performansını optimize etme


13

Bağlantılı yazı tipi kilit eşleşmesinin bir varyantını gerçekleştirmek istiyorum. Bir ad listesi ile başlayan işlev tanımlarım var ve bu adların işlev gövdesi içinde vurgulanmasını istiyorum.

Bunu yapan bir işlev oluşturdum ve jit-lock-register ile bir jit-lock işlevi olarak kaydettirdim, ancak performans oldukça zayıf ve daha büyük dosyalarda kaydırma gecikmeleri.

  • Performansı nasıl ölçebilirim? Eğer sadece fonksiyonumu büyük bir dosyada çağırırsam (elp ile önce veya sonra float zamanı ile) çılgınca değişen performans elde ederim, 0.65 ila 12 saniye arasında bir şey alır. Yazı tipi kilidi performansını karşılaştırmanın önerilen bir yolu var mı?
  • Font-lock-anahtar sözcüklerinde tanımlanan bağlantılı bir eşleştirici ile jit-lock-register yoluyla bir işlev ekleme arasında performansta herhangi bir fark var mı?

Düzenleme: Performans değişkenliği çöp toplama ile ilgili gibi görünüyor, jit kilit fonksiyonu benim çağrılar çöp toplama çalıştırılana kadar her çağırma ile tekrar yavaş yavaş olsun, hangi noktada tekrar hızlı olsun.


İlk öğe için profil oluşturucuyu deneyin.
Malabarba

Profilerimi de kodumun zaman alan kısımlarını görebildim (ve kullandım), ancak performans çok tutarsız olduğundan, yaptığım değişikliklerin bir gelişme olup olmadığını söylemek zor.
Joakim Hårsman

Test edebileceğimiz bir kod var mı? Bu bize çok yardımcı olabilir.
PythonNut

1
Profil oluşturma veya mikro optimizasyonlarla ilgili olmasa da, kendi başına: font-lock-studio paketini, font-lock performansını anlamak için başka bir yararlı araç olarak buldum . Diğer etkileşimli adım hata ayıklayıcıların da yardımcı olabileceği gibi yardımcı olabilir - yürütme yollarının beklediğiniz gibi olmadığını keşfedebilirsiniz ve bu ana performans sorunudur.
Greg Hendershott

Font-lock-studio hakkındaki ipucu için teşekkürler, harika! Yine de jit-lock-fonksiyonları ile yardımcı olmaz, ama her şeyde emin.
Joakim Hårsman

Yanıtlar:


8

Çılgınca değişen performansın çöp toplama ile ilgili olduğu ortaya çıktı. Bir çöp toplama çalıştırılana kadar işleve yapılan her çağrı yavaşlar. Hisse senedi emacs ile gc, her birkaç saniyede bir çalıştırıldı, ancak gc-eksilerini eşik değerini 20 MB'ye ayarlayan başlatma süresini iyileştirmek için init.el'de bir satırım vardı ve bu, gc'nin daha seyrek çalıştırıldığı anlamına geliyor ve kıyaslamaların Bir gc birkaç dakika sonra çalıştırılıncaya kadar daha yavaş ve yavaş zamanlama rapor edin, sonra zaman düşecek ve tekrar hızlı olacaktır.

Varsayılan gc-cons-threshhold'a geri döndükten sonra, kıyaslama daha kolay hale geldi.

Sonra yerleşik profiler ( M-x profiler-start) ile bellek için profilli ve sözdizimi-ppss çağrıları en çok tahsis neden olduğunu keşfetti, bu yüzden sözdizimi-ppss daha az sıklıkta aramak için bazı optimizasyon sonra kabul edilebilir performans elde etti.

Jit-lock-mode (jit-lock-register ile bir işlev eklemek) kullanmak, çok satırlı yazı tipi kilidinin güvenilir bir şekilde çalışmasını sağlamanın en kolay yolu gibi görünüyor, bu yüzden seçtiğim yöntem buydu.

Düzenleme: Performansın hala çok büyük arabelleklerde yeterince iyi olmadığını keşfettikten sonra, dahili Emacs profiler ( M-x profiler-start) ile performans iyileştirmelerini ölçerek, cpu kullanımı ve tahsisini optimize etmek için çok zaman harcadım . Bununla birlikte, Emacs çok büyük arabelleklerde hızlı bir şekilde kaydırılırken hala kekeliyor ve asılı kalıyordu. Kaydettiğim jit kilit işlevinin jit-lock-registerkaldırılması kekemeliği ve askıda kalmayı ortadan kaldırır, ancak profilleme jit kilit işlevinin yaklaşık 8 ms'de tamamlandığını gösterdi ve bu da düzgün kaydırma için yeterince hızlı olmalıdır. Çağrıyı kaldırmak jit-lock-registerve bunun yerine normal bir font-lock-keywords eşleştiricisi kullanmak sorunu çözdü.

TLDR: Bunu yapmak yavaştı ve kekeliyordu:

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

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

Bunu yapmak hızlıydı ve kekelemedi:

(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))))

Kullandığınız kodu paylaşabilir misiniz? Çözümünüz aynı şeyi başarmak isteyen başkalarına yardımcı olabilir.
Manuel Uberti

Gerçekten herhangi bir kod kullanmadım, ben sadece sözdizimi-ppss daha az aradım. : Burada söz konusu kodunu kontrol edebilirsiniz bitbucket.org/harsman/dyalog-mode/src/... için bak dyalog-fontify-locals.
Joakim Hårsman

Sanırım dyalog-fontify-locals-matcherolmalı my-font-lock-matcherve biri endolmalı limit. Her neyse, gerçekten ilginç bir keşif!
Lindydancer

@Lindydancer: Evet, teşekkür ederim. Sabit.
Joakim Hårsman

1
Re:, gc-cons-thresholdsadece başlangıç ​​zamanını iyileştirmek için dahili değerlerle uğraşıyorsanız, emacs-startup-hookdaha sonra bunları geri yüklemek için kullanmanızı öneririm .
phils
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.