การเพิ่มประสิทธิภาพการล็อคแบบอักษร


13

ฉันต้องการที่จะทำการจับคู่ชุดตัวอักษรของตัวล็อค ฉันมีคำจำกัดความของฟังก์ชั่นที่เริ่มต้นด้วยรายชื่อและฉันต้องการให้ชื่อเหล่านั้นถูกเน้นอยู่ภายในส่วนของฟังก์ชั่น

ฉันได้สร้างฟังก์ชั่นที่ทำสิ่งนี้และลงทะเบียนเป็นฟังก์ชั่น jit-lock ด้วย jit-lock-register อย่างไรก็ตามประสิทธิภาพการทำงานค่อนข้างแย่และการเลื่อนล่าช้าในไฟล์ขนาดใหญ่

  • ฉันจะวัดประสิทธิภาพได้อย่างไร ถ้าฉันเพียงแค่เรียกฟังก์ชั่นของฉันในไฟล์ขนาดใหญ่ (ที่มีเวลาลอยก่อนและหลังหรือด้วย elp) ฉันได้รับประสิทธิภาพที่แตกต่างกันอย่างดุเดือดมันใช้เวลาตั้งแต่ 0.65 ถึง 12 วินาที มีวิธีแนะนำให้ใช้ประสิทธิภาพการล็อคแบบอักษรมาตรฐานหรือไม่
  • มีประสิทธิภาพแตกต่างกันหรือไม่ระหว่างตัวจับคู่แบบยึดที่กำหนดไว้ในแบบอักษร - ล็อค - คำหลักและเพิ่มฟังก์ชั่นผ่านทาง jit-lock-register?

แก้ไข: ดูเหมือนว่าความแปรปรวนของประสิทธิภาพนั้นเกี่ยวข้องกับการรวบรวมขยะการเรียกใช้ฟังก์ชั่น jit-lock ของฉันช้าลงอย่างต่อเนื่องทุกครั้งที่เรียกใช้จนกว่าการรวบรวมขยะจะเริ่มขึ้น


สำหรับรายการแรกให้ลองใช้ตัวสร้างโปรไฟล์
Malabarba

ฉันสามารถ (และมี) ใช้ผู้สร้างโปรไฟล์ด้วยเช่นกันว่าส่วนใดของรหัสของฉันที่ต้องใช้เวลา แต่เนื่องจากประสิทธิภาพไม่สอดคล้องกันดังนั้นจึงเป็นการยากที่จะบอกได้ว่าการเปลี่ยนแปลงใด ๆ ที่ฉันทำนั้นเป็นการปรับปรุงหรือไม่
Joakim Hårsman

คุณมีรหัสที่เราสามารถทดสอบได้ไหม นั่นอาจช่วยเราได้มาก
PythonNut

1
แม้ว่าจะไม่ได้เกี่ยวกับการทำโปรไฟล์หรือการเพิ่มประสิทธิภาพขนาดเล็ก แต่อย่างใด: ฉันพบแพ็คเกจfont-lock-studioเป็นเครื่องมือที่มีประโยชน์อีกอย่างหนึ่งสำหรับทำความเข้าใจเกี่ยวกับประสิทธิภาพการล็อคแบบอักษร มันสามารถช่วยได้เช่นเดียวกับดีบักเกอร์แบบอินเทอร์แอคทีฟอื่น ๆ ที่สามารถช่วยได้ - คุณอาจพบว่าเส้นทางการดำเนินการไม่ใช่สิ่งที่คุณคาดหวังและนั่นคือปัญหาประสิทธิภาพหลัก
Greg Hendershott

ขอบคุณสำหรับเคล็ดลับเกี่ยวกับ font-lock-studio มันยอดเยี่ยมมาก! แม้ว่าจะไม่ได้ช่วยในการฟังก์ชั่น jit-lock แต่ก็แน่ใจได้ว่าจะทำอย่างอื่น
Joakim Hårsman

คำตอบ:


8

ปรากฎว่าประสิทธิภาพที่แตกต่างกันนั้นเกี่ยวข้องกับการเก็บขยะ การเรียกใช้ฟังก์ชันแต่ละครั้งจะช้าลงจนกว่าจะมีการรวบรวมขยะ เมื่อใช้ emacs หุ้น gc จะทำงานทุก ๆ สองสามวินาที แต่ฉันมีบรรทัดใน init.el ของฉันเพื่อปรับปรุงเวลาเริ่มต้นที่ตั้งค่า gc-cons-threshold เป็น 20 MB และนั่นหมายความว่า gc ทำงานได้ไม่บ่อยนัก รายงานเวลาที่ช้าลงและช้าลงจนกว่า gc จะทำงานหลังจากผ่านไปสองสามนาทีจากนั้นเวลาจะลดลงและจะเร็วขึ้นอีกครั้ง

หลังจากเปลี่ยนกลับเป็น gc-cons-threshhold เริ่มต้นการเปรียบเทียบก็ง่ายขึ้น

ฉันสร้างโปรไฟล์สำหรับหน่วยความจำด้วย built in profiler ( M-x profiler-start) และค้นพบว่าการเรียกใช้ไวยากรณ์ -ppss ทำให้เกิดการจัดสรรมากที่สุดดังนั้นหลังจากการเพิ่มประสิทธิภาพบางอย่างในการเรียกใช้ไวยากรณ์ -ppss บ่อยครั้งที่ฉันได้รับประสิทธิภาพที่ยอมรับได้

การใช้ jit-lock-mode (การเพิ่มฟังก์ชั่นผ่าน jit-lock-register) ดูเหมือนจะเป็นวิธีที่ง่ายที่สุดในการทำให้การล็อคแบบอักษรหลายบรรทัดทำงานได้อย่างน่าเชื่อถือดังนั้นนั่นเป็นวิธีที่ฉันเลือก

แก้ไข: หลังจากค้นพบว่าประสิทธิภาพการทำงานยังไม่ดีพอในบัฟเฟอร์ที่มีขนาดใหญ่มากฉันใช้เวลาส่วนใหญ่ในการปรับแต่งการใช้และการจัดสรรซีพียูให้มากที่สุดวัดการปรับปรุงประสิทธิภาพด้วยตัวสร้างโปรไฟล์ Emacs ( M-x profiler-start) อย่างไรก็ตาม Emacs ยังคงพูดติดอ่างและแขวนเมื่อเลื่อนผ่านบัฟเฟอร์ขนาดใหญ่มากอย่างรวดเร็ว การลบฟังก์ชั่น jit-lock ที่ฉันลงทะเบียนไว้jit-lock-registerจะลบการพูดติดอ่างและแฮงค์ แต่การทำโปรไฟล์แสดงให้เห็นว่าฟังก์ชั่น jit-lock นั้นเสร็จสมบูรณ์ในเวลาประมาณ 8 ms ซึ่งน่าจะเร็วพอสำหรับการเลื่อนที่ราบรื่น การลบการโทรออก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

ฉันไม่ได้ใช้รหัสเฉพาะใด ๆ ฉันเพิ่งเรียกว่า syntax-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.