मैं Emacs को धीमा करने वाली बेहद लंबी लाइनों को कैसे रोकूँ?


72

जिस फ़ाइल में मैं जा रहा हूँ, उसमें कितने नए दृश्य हैं, इस पर निर्भर करता है कि मैं बेहद विविध प्रदर्शन देखता हूँ।

यहाँ एक उदाहरण है। मेरे पास दो JSON फाइलें हैं:

$ wget https://github.com/Wilfred/ReVo-utilities/blob/a4bdc40dd2656c496defc461fc19c403c8306d9f/revo-export/dictionary.json?raw=true -O one_line.json
$ python -m json.tool <one_line.json >pretty_printed.json

ये एक ही सामग्री के साथ दो JSON फाइलें हैं। one_line.jsonबिना किसी नए अंक के JSON की 18MiB है। pretty_printed.jsonइसमें नए लिंक और व्हॉट्सएप जोड़े गए हैं, जो इसे 41MiB बनाता है।

हालाँकि, कई लाइनों में विभाजित बड़ी फ़ाइल Emacs में खोलने के लिए बहुत तेज़ है, जावास्क्रिप्ट मोड और फंडामेंटल मोड दोनों में।

Emacs के पास लंबी लाइनों के साथ ऐसा खराब प्रदर्शन क्यों है, क्योंकि यह वास्तव में कम बाइट्स है? क्या कुछ ऐसा है जो मैं Emacs के बाहर डेटा को पुन: स्वरूपित किए बिना प्रदर्शन को बेहतर बनाने के लिए कर सकता हूं?


2
वास्तव में एक उत्तर नहीं है, लेकिन उपयोग का हो सकता है: View Large Files(vlf) एक मामूली मोड है जिसका उद्देश्य बड़ी फ़ाइलों को बैचों में लोड करके संपादन में मदद करना है । डिस्क्लेमर: मैंने कभी इसका उपयोग नहीं किया है और मुझे नहीं पता कि यह बैचों में भी लंबी लाइनों को संभालता है या नहीं ।
११

3
इस तरह के व्यवहार को जानना, और विशेष रूप से जब एक लॉग को पढ़ने के खिलाफ खुद को संरक्षित करने की कोशिश करना जो लंबी लाइन से बाहर निकलता है, तो मैं अक्सर $ tail -f /some/file | fold -sशेल बफर में कुछ ऐसा करता हूं । यह स्पष्ट रूप से संपादन के लिए अच्छा नहीं है, लेकिन पढ़ने में बहुत मदद करता है।
wvxvw

जवाबों:


50

Emacs की लंबी लाइनों की हैंडलिंग बहुत अच्छी तरह से अनुकूलित नहीं है। कई ऑपरेशन के लिए, Emacs को बार-बार पूरी लाइन को स्कैन करना पड़ता है। उदाहरण के लिए, एक लाइन प्रदर्शित करने के लिए, Emacs को लाइन की ऊँचाई का पता लगाना होता है, जिसके लिए सबसे लंबी ग्लिफ़ खोजने के लिए पूरी लाइन को स्कैन करना पड़ता है। इसके अतिरिक्त, द्विदिश प्रदर्शन के लिए स्कैन करने में बहुत समय लगता है। आप कुछ अतिरिक्त जानकारी प्राप्त कर सकते हैं, उदाहरण के लिए, cache-long-line-scans( cache-long-scans24.4 में बदला हुआ) का डॉकस्ट्रिंग ।

आप कोशिश करते हैं और देखते हैं की स्थापना करता है, तो कर सकते हैं bidi-paragraph-directionकरने के लिए left-to-rightआप के लिए गति को बेहतर बनाता है [स्थापित करने bidi-display-reorderingके लिए nil, और अधिक या कम एक ही करता है, लेकिन केवल आंतरिक / डीबगिंग उद्देश्यों के लिए है]। यह लाइन स्कैन के लिए एक महत्वपूर्ण योगदानकर्ता को हटाता है, लेकिन दुख की बात है कि केवल एक ही नहीं।

सबसे अच्छा विकल्प newlines जोड़ने के लिए है। आप JSON फ़ाइल को पाइप के माध्यम से पाइप कर सकते हैं जैसे python -c 'import json, sys ; json.dump(json.load(sys.stdin), sys.stdout, indent=2)'कि नई लिंक जोड़ने और सामान्य रूप से पठनीयता में सुधार करने के लिए।


4
जिज्ञासा से बाहर, यह कुछ ऐसा है जिसे एल्गोरिदम में सुधार नहीं किया जा सकता है?
पायथनटन

9
जब एक संपादक की अंतर्निहित डेटा संरचना को चुनते हैं, तो आपको कुछ पेशेवरों और विपक्षों के बीच चयन करना होगा। Emacs एक गैप बफर का उपयोग करता है , जो प्रविष्टि और विलोपन के लिए एक उच्च स्थान कुशल डेटा संरचना है, लेकिन यह लाइन-आधारित संचालन को धीमा कर देता है क्योंकि आपको एक नई रेखा के लिए क्रमिक रूप से स्कैन करना होगा। Emacs एक अलग डेटा संरचना का उपयोग कर सकते हैं, लेकिन यह अन्य संचालन को धीमा कर देगा। Emacs पहले से ही एक लाइन कैश का उपयोग करता है, लेकिन यह वास्तव में सभी स्थितियों में मदद नहीं करता है। इसलिए, आसानी से एल्गोरिथ्म में सुधार नहीं हुआ है, लेकिन प्रोफाइलिंग और अनुकूलन कभी भी दर्द नहीं करता है। :-)
जोर्गेन शेफ़र

4
(setq-default bidi-display-reordering nil)- कुछ उपयोगकर्ताओं को यह महसूस नहीं हो सकता है कि यह एक बफर-लोकल वैरिएबल है, जिसके लिए एक डिफ़ॉल्ट सेटिंग की आवश्यकता हो सकती है, जिस हद तक उपयोगकर्ता यह चाहता है कि वह ग्लोबल हो। काश मैंने इसे अपने init.elवर्षों पहले जोड़ा होता ... लेकिन अब यह कम से कम है। आपका बहुत धन्यवाद!!!
२०

मेरे मामले में यह एक बड़ा कामचलाऊ काम नहीं था (वास्तव में बेस 64 डॉक्युमेंट्स बॉडी के साथ लंबी जोंस लाइन्स), लेकिन
बेजिंग

1
वर्तमान Emacs अनुरक्षक, एली, जिसने BIDI कोड लिखा था, इसे स्विच ऑफ करने के बारे में लिखता है bidi-display-reordering: "मेरी एक टिप्पणी यह ​​है कि बीड़ी-डिस्प्ले-रीऑर्डरिंग को अक्षम करना ... डिस्प्ले इंजन को ऐसी स्थिति में डालता है जिसका परीक्षण नहीं किया जा रहा है, और विसंगतियों का कारण बन सकता है। और यहां तक ​​कि बग (क्योंकि कोड के कुछ अंश इस धारणा के तहत लिखे गए थे कि यह चर कभी शून्य नहीं है)। "
क्लेमेंट

18

मैंने इसके साथ कुछ संक्षिप्त प्रयोग किए, जिसमें एक नकली कॉपी का उपयोग किया गया था। font-lock-modeऔर flycheck-modeदोनों ने धीमेपन के लिए योगदान दिया, जैसा कि किया js2-mode, और prettify-symbols-modeline-number-modeऔर column-number-modeमामूली प्रभाव पड़ा। एक बार मैंने सभी अलग-अलग तरीकों को बंद कर दिया था, हालांकि प्रदर्शन अपेक्षाकृत तेज़ था। C-h mसक्षम और उपयोग किए गए विभिन्न मोड को अक्षम करना या बस स्विच करने का प्रयास करना शुरू करें fundamental-mode

दिलचस्प रूप से hexl-modeमैं किसी भी मुद्दे के बिना फ़ाइल के माध्यम से उड़ सकता था, हालांकि स्पष्ट रूप से कॉलम काफी कम थे। दुर्भाग्य से visual-line-modeवास्तव में चीजों को धीमा कर दिया।

मेरा अनुमान है कि वाक्यविन्यास तालिका लाइन अंत में प्रसंस्करण को रोकने के लिए खुश है, और जब यह सब एक पंक्ति में है तो इसे हर अपडेट पर सब कुछ वापस करना होगा।


2
क्या आप फ्लाईचेक के ट्रैकर पर बग रिपोर्ट खोल सकते हैं? मुझे पूरा यकीन है कि हम मुद्दों के कारण लंबी लाइनें नहीं चाहते हैं, और Emacs + Flycheck को Emacs (जो अभी भी बहुत बुरा है) से भी बदतर नहीं होना चाहिए।
क्लेमेंट

16

मैंने http://www.emacswiki.org/emacs/OverLongLineMode अपलोड किया है

यह लाइब्रेरी आपको सरल लाइन-लेंथ थ्रेसहोल्ड सेट करने में सक्षम करती है, जिसके आगे fundamental-modeइसके सामान्य मोड (केवल प्रोग्रामिंग मोड के लिए) के बजाय फ़ाइल के लिए एक संस्करण का उपयोग किया जाएगा।

इन पंक्तियों के साथ संभावित रूप से कुछ डिफ़ॉल्ट रूप से Emacs में जोड़ा जा सकता है, लेकिन यह Emacs की प्राथमिक समस्या के लिए एक अंतरिम हल हो सकता है जिससे ऐसी फ़ाइल का सामना करने पर क्रॉल धीमा हो।

nb यह उस कोड पर सुधार है जिसे मैंने शुरू में इस उत्तर में पोस्ट किया था, लेकिन अभी भी एक कार्य-प्रगति है। परीक्षण न्यूनतम रहा है। टिप्पणियों का स्वागत किया जाता है।

अन्य (इसके अलावा css-mode) गैर- prog-modeप्रमुख प्रमुख मोड के लिए डिफ़ॉल्ट रूप से समर्थन करने के सुझावों का भी स्वागत किया जाता है।


1
अब इसमें और सुधार हुआ, और शर्म से नाम बदलकर so-long.el :) (उपरोक्त लिंक रीडायरेक्ट हो जाएगा)। इसके साथ और भी बहुत कुछ किया जा सकता है, लेकिन यह 100% कार्यात्मक और उपयोगी है।
फिल्स

यह वास्तव में अच्छा समाधान है (इसे MELPA पर देखना पसंद करेंगे), लेकिन one_line.json को खोलते समय मेरी Emacs की आवृत्ति अभी भी बहुत धीमी है। मुझे लगता है कि अगर यह पहली बार प्रमुख मोड को सक्रिय नहीं करता है तो यह काफी तेज होगा।
विल्फ्रेड ह्यूजेस

3
इसे फिर से पढ़ना और प्रश्न से आपकी one_line.json फ़ाइल का उपयोग करते हुए, मैंने डिफ़ॉल्ट-कॉन्फ़िगर Emacs 25.3 और 26.0.91 की प्रतीक्षा करने के बाद उन्हें उस फ़ाइल को खोलने के लिए कहने के बाद प्रतिक्रिया देने के लिए कहा (एक मिनट से अधिक प्रतीक्षा करने के बाद), जबकि अपना खुद का so-long.elसक्रिय के साथ कॉन्फ़िगर फ़ाइल को 2 सेकंड के भीतर खोला गया। वास्तव में फ़ाइल को संपादित करना अभी भी समस्याग्रस्त है (उदाहरण के लिए 'अगली पंक्ति में जाने की कोशिश करने में बहुत लंबा समय लगेगा), लेकिन फिर भी यह मेरे द्वारा लिखी गई लाइब्रेरी की उपयोगिता में मेरा विश्वास बहाल करता है, इसलिए मुझे अपनी योजनाओं को फिर से शुरू करना चाहिए। यह जीएनयू ELPA में जोड़ने के लिए ...
फिल्स

1
क्या यह (एम) ईएलपीए में है?
बिंकी

3
स्थिति रिपोर्ट: संस्करण 1.0 so-long.el(कई संवर्द्धन के साथ) एमएसीएस 27 के वर्तमान विकास संस्करणों में शामिल है, और निकट भविष्य में कुछ समय के लिए जीएनयू ईएलपीए के माध्यम से उपलब्ध होगा (एमएसीएस के पहले संस्करणों के लिए)।
फिल्स

7

मुझे उम्मीद है कि आप पाएंगे कि अंतर के कारण है font-lock। जब फ़ाइल के सबसेट पर फॉन्टिफिकेशन किया जाना है जो विंडो में दिखाई देता है, तो यह फॉन्टिफिकेशन रीजन को पहले बढ़ाकर आगे बढ़ता है, जैसे कि इसमें पूर्ण सिमेंटिक यूनिट्स शामिल होंगी। इसके लिए font-lock-extend-region-functionsकोड देखें । पूर्ण रेखाओं को शामिल करने के लिए इस क्षेत्र का विस्तार करना सामान्य है। जब रेखाएं बहुत लंबी होती हैं, तो यह वास्तव में दिखाई देने वाली सामग्री के बहुत बड़े हिस्से में किए जाने वाले फ़ॉन्टकरण को जन्म दे सकती है।

इसके अतिरिक्त, जब newlines खुद को अर्थ संबंधी जानकारी देते हैं, तो उनकी अनुपस्थिति का मतलब कभी-कभी हो सकता है कि फ़ॉन्ट लॉक के लिए regexp पैटर्न को यह निर्धारित करने के लिए आगे स्कैन करना होगा कि वे मेल खाते हैं या नहीं।


7

मैं आमतौर पर टैग्स (जैसे HTML, XML, JSON) द्वारा लंबी लाइनों और इंडेंट को अनियंत्रित करता हूं।

इस तरह के ऑपरेशन को संभव बनाने के लिए मैं जोड़ता हूं:

(setq line-number-display-limit large-file-warning-threshold)
(setq line-number-display-limit-width 200)

(defun my--is-file-large ()
  "If buffer too large and my cause performance issue."
  (< large-file-warning-threshold (buffer-size)))

(define-derived-mode my-large-file-mode fundamental-mode "LargeFile"
  "Fixes performance issues in Emacs for large files."
  ;; (setq buffer-read-only t)
  (setq bidi-display-reordering nil)
  (jit-lock-mode nil)
  (buffer-disable-undo)
  (set (make-variable-buffer-local 'global-hl-line-mode) nil)
  (set (make-variable-buffer-local 'line-number-mode) nil)
  (set (make-variable-buffer-local 'column-number-mode) nil) )

(add-to-list 'magic-mode-alist (cons #'my--is-file-large #'my-large-file-mode))

मैं रेखा को रेगेक्स से विभाजित करता हूं, एक्सएमएल के लिए C-M-% >< RET >NL< RET !:।

Emacs के बाद लंबी लाइनों का विभाजन हुआ - कई *-modesऔर पुन: इंडेंट कोड को सक्षम करना संभव है ।

नोट के लिए: जब एक हीन प्रक्रिया लंबी लाइनें उत्पन्न करती है तो धीमी गति से बचाव कैसे करें?


4

मैंने इस समस्या के लिए अपना स्वयं का समाधान यहां बनाया: https://github.com/rakete/too-long-lines-mode

मैं फ़िल्स समाधान से संतुष्ट नहीं था जो एक बफर को मूलभूत-मोड में बहुत लंबी लाइनों के साथ स्विच करता है, मैं एक समाधान चाहता था जो मुझे सिंटैक्स हाइलाइटिंग और अन्य प्रमुख-मोड सुविधाओं को रखने की सुविधा देता है। इसलिए मैंने एक छोटी-सी विधा बनाई जो ओवरली लंबी लाइनों के अधिकांश पात्रों को छिपाने के लिए ओवरले का उपयोग करती है।

यह समस्या के इर्द-गिर्द काम करता है और बहुत लंबी लाइनों वाले बफ़र्स में भी एमएसीएस को बेकार कर देता है, बिना फंडामेंटल-मोड के वापस आने के लिए।


2

मेरे Emacs सेटअप में मेरे पास कस्टम फॉन्टिफिकेशन के साथ एक मोड है, यानी जहां मैं सेट करता हूं font-lock-defaults। एक सिंगल पेज डाउन 30000 कैरेक्टर लाइन का हिस्सा प्रदर्शित करने के लिए 30 सेकंड का उपयोग करेगा। यह धीमा रीएग्क्स बैकट्रैकिंग को कम करके तय किया गया था। के बजाय:

  ("* एक अधूरी आज्ञा के साथ समाप्त हुआ *" 0 फॉन्ट-लॉक-कमेंट-फेस)

यह करो

  ("^। \ {1,80 \} एक अपूर्ण कमांड के साथ समाप्त हुआ *" 0 फॉन्ट-लॉक-कमेंट-फेस)

यह सवाल का जवाब नहीं है, जो विशेष रूप से font-lock-defaultsमेल खाने या regexp के बारे में नहीं है ।
ड्रू

1
@Drew आदर्श regex से भी कम है बनाने हालांकि ... लंबी लाइनों पर धीमी गति से font-लॉक
wasamasa

1
@ वासमासा: हाँ। सवाल खुद बहुत व्यापक है, IMO। जब लंबी लाइनें शामिल होती हैं तो बहुत सी चीजें होती हैं जो Emacs को धीमा कर सकती हैं (और किन कार्यों के लिए?)।
ड्रू

3
मुझे नहीं लगता कि सवाल व्यापक है (" लंबी लाइनें एमएसीएस को धीमा क्यों बनाती हैं ")? और न ही मुझे लगता है कि उत्तर प्रश्न को संबोधित नहीं करता है (" एक संभावित कारण सबऑप्टिमल रीजैक्स हैं")। अन्य उत्तर अन्य कारणों को संबोधित कर सकते हैं। एक फ़ाइल को लंबी लाइनों के साथ खोलना एक विषय को व्यापक बनाना नहीं है क्योंकि यह कई कारणों से समस्याग्रस्त हो सकता है, कभी-कभी आपके पास ऐसी फाइलें होती हैं और आपको उन्हें देखना पड़ता है, अधिमानतः Emacs का उपयोग करना।
tarsius

1

मेरे शेल-मोड बफ़र्स (एमएक्स शेल) में, मैं खुद sed -r 's/(.{2000}).*/\1/' -uको लंबी लाइनों से बचने के लिए पाइपिंग करता हूं ।


यह प्रश्न के दूसरे भाग का उत्तर देता है: प्रदर्शन में सुधार कैसे करें। यह पहले भाग को संबोधित नहीं करता है (जो ठीक है): " एमएसीएस के पास लंबी लाइनों के साथ ऐसा खराब प्रदर्शन क्यों है ?"
ड्रू

0

मैं dired-modeलंबी लाइनों वाली बड़ी फ़ाइलों में खोलने के लिए निम्न फ़ंक्शन का उपयोग करता हूं :

(defun dired-find-file-conservatively ()
   (interactive)
   (let ((auto-mode-alist nil))
     (dired-find-file)
     ;; disable costly modes
     (fundamental-mode)
     (setq-local bidi-display-reordering nil)
     (when (boundp 'smartparens-mode)
       (smartparens-mode -1))))

(define-key dired-mode-map (kbd "S-<return>") 'dired-find-file-conservatively)

0

यहाँ एक वर्कअराउंड है, जो emacs-devel से लिया गया है :

(add-hook 'find-file-hook
          (defun my-find-file-care-about-long-lines ()
            (save-excursion
              (goto-char (point-min))
              (when (and (not (eq major-mode 'image-mode))
                         (search-forward-regexp ".\\{2000\\}" 50000 t)
                         (y-or-n-p "Very long lines detected - enable 
longlines-mode? "))
                (require 'longlines)
                (longlines-mode +1)))))

24.4 के रूप में Emacs में longlines-modeobsoleted के रूप में चिह्नित किया गया है visual-line-mode
अलेक्जेंडर I. ग्रेफोव

हालाँकि दोनों विशेषताएं पर्दे के पीछे बहुत अलग चीजें करती हैं, और visual-line-modeप्रश्न में समस्या के साथ मदद नहीं करती हैं, जबकि longlines-modeकरती हैं। इस कारण से, मुझे उम्मीद है कि longlines.el को गैर-वंचित स्थिति में बहाल किया जाएगा।
फिल्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.