emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* [ISSUE] org-mode fill paragraph is slow and suspend often
@ 2021-10-26  6:18 Christopher M. Miles
  2021-10-26  8:21 ` Ihor Radchenko
  0 siblings, 1 reply; 5+ messages in thread
From: Christopher M. Miles @ 2021-10-26  6:18 UTC (permalink / raw)
  To: Org Mode


[-- Attachment #1.1: Type: text/plain, Size: 13005 bytes --]



When I press [M-q] on the following org-mode buffer content:

#+begin_src org
,* 绵羊是太阳能农场的优秀管理员
:PROPERTIES:
:SOURCE: 奇客Solidot–传递最新科技情报
:DATE(original): [2021-10-25 Mon 17:28]
:DATE: [2021-10-26 Tue]
:END:

有利于放养家畜和有利于太阳能发电的地方经常重叠。它们都需要平坦、阳光充足,没有高大植被的开阔地。因此
太阳能生产商正越来越多地租用农田运营。

太阳能产量的增加具有环境效益,但是其代价可能是农业产量的下降。因而人们越来越有兴趣寻找在同一个地方结
合农业和太阳能生产的方法。对于康奈尔大学农业综合企业副教授 Todd Schmit 来说,[[https://arstechnica.com/science/2021/10/shepherds-can-cash-in-on-their-sheep-grazing-around-solar-panels/][问题的答案是羊群]]。

这仍然是一个新领域,部分农民正和太阳能生产商合作,在后者的土地上放牧。太阳能生产商付钱给农民,让他们
把羊送到他们的太阳能农场,羊会吃掉杂草和其他可能阻挡阳光到达太阳能板的植物。

羊得到了食物,农民得到了报酬,而太阳能生产商则在不使用割草机和除草机的情况下管理农场的植被------割草
机和除草机很难伸到太阳能面板下方,而且需要使用化石燃料。American Solar Grazing Association(ASGA)的
[[https://solargrazing.org/wp-content/uploads/2021/02/Solar-Site-Sheep-Grazing-in-NY.pdf][报告]]显示,该行业自 2017 年以来,一直在纽约州扩张。帝国州(纽约州)报告指出,目前有 900 英亩的太阳能
生产土地正在放牧。增长空间仍然很大。
#+end_src

Emacs often suspend for a long time.

So I take a profiling test with Emacs profiler. Seems =org-fill-element= spend a lot of CPU and memory.

Here is the result:

CPU Profiler Report:

#+begin_example
        3623  65% - command-execute
        3623  65%  - call-interactively
        3623  65%   - funcall-interactively
        3141  56%    - org-fill-paragraph
        3141  56%     - let
        3141  56%      - cond
        3141  56%       - let
        3141  56%        - unwind-protect
        3141  56%         - progn
        3140  56%          - while
        2096  37%           - org-fill-element
        2090  37%            - let
        2090  37%             - unwind-protect
        2089  37%              - progn
        2079  37%               - let
        2044  36%                - save-excursion
        2032  36%                 - org-element-at-point
        2027  36%                  - let
        1546  27%                   - if
        1473  26%                    - progn
        1473  26%                     - if
        1473  26%                      - if
        1467  26%                       - org-element--cache-sync
        1467  26%                        - if
        1467  26%                         - progn
        1441  25%                          - save-current-buffer
        1416  25%                           - if
        1410  25%                            - let
        1400  25%                             - let
        1334  23%                              - catch
        1332  23%                               - and
        1332  23%                                - org-indent-add-properties
        1332  23%                                 - let
        1332  23%                                  - unwind-protect
        1332  23%                                   - progn
        1332  23%                                    - save-excursion
        1332  23%                                     - save-restriction
        1301  23%                                      - let
        1301  23%                                       - catch
        1301  23%                                        - and
        1301  23%                                         - org-indent-add-properties
        1301  23%                                          - let
        1301  23%                                           - unwind-protect
        1301  23%                                            - progn
        1301  23%                                             - save-excursion
        1301  23%                                              - save-restriction
        1301  23%                                               - let*
        1296  23%                                                - let*
        1296  23%                                                 - unwind-protect
        1296  23%                                                  - progn
        1296  23%                                                   - while
        1296  23%                                                    - cond
        1155  20%                                                       and
          87   1%                                                     - org-at-item-p
          83   1%                                                      - save-excursion
          80   1%                                                       - and
          65   1%                                                        - org-list-in-valid-context-p
          64   1%                                                         - not
          63   1%                                                          - org-in-block-p
          63   1%                                                           - let
          60   1%                                                            - unwind-protect
          60   1%                                                             - progn
          60   1%                                                              + catch
           8   0%                                                        + looking-at
          40   0%                                                     + org-indent-set-line-properties
           4   0%                                                     + let*
           4   0%                                                + or
           1   0%                                                + org-get-limited-outline-regexp
          30   0%                                      + let*
           1   0%                                      + if
           1   0%                               + while
           5   0%                             + if
          51   0%                    + and
          10   0%                    + if
           4   0%                    + org-element--cache-active-p
           3   0%                    + eq
         481   8%                   + setq
           1   0%                    setq
          14   0%                + let*
        1036  18%           + org-backward-paragraph
         476   8%    + counsel-M-x
           3   0%    + next-line
           2   0%    + end-of-buffer
           1   0%    + previous-line
        1917  34% - ...
        1917  34%    Automatic GC
          17   0% + timer-event-handler
          12   0% + redisplay_internal (C function)
           1   0% + global-aggressive-indent-mode-check-buffers
           1   0% + emojify-update-visible-emojis-background-after-command

#+end_example

Memory Profiler Report

#+begin_example
    264,854,075  76% - command-execute
    264,854,075  76%  - call-interactively
    264,854,075  76%   - funcall-interactively
    255,418,275  73%    - org-fill-paragraph
    255,418,275  73%     - let
    255,418,275  73%      - cond
    255,204,659  73%       - let
    255,204,659  73%        - unwind-protect
    255,204,659  73%         - progn
    255,204,659  73%          - while
    180,115,491  51%           - org-backward-paragraph
    180,115,491  51%            - if
    180,115,491  51%             - while
    180,115,491  51%              - org--backward-paragraph-once
    176,778,067  50%               - save-restriction
    176,778,067  50%                - cond
    165,159,987  47%                 - let*
    141,442,819  40%                  - org--paragraph-at-point
    138,407,875  39%                   - let*
    107,627,587  31%                    - org-element-at-point
    106,599,043  30%                     - let
     60,513,047  17%                      - setq
     60,513,047  17%                       - if
     59,896,343  17%                        - condition-case
     56,847,671  16%                         - org-element--parse-to
     56,847,671  16%                          - catch
     26,082,351   7%                           - let
     22,117,552   6%                            - unwind-protect
     22,117,552   6%                             - progn
     20,683,728   5%                              - save-excursion
     20,683,728   5%                               - save-restriction
     15,229,632   4%                                - let*
      6,096,288   1%                                 + let
      3,049,728   0%                                   and
      2,037,024   0%                                   cond
     46,085,996  13%                      + if
     20,238,240   5%                    + if
      7,524,000   2%                    + cond
      9,968,048   2%                  + cond
        995,808   0%                    if
      2,436,160   0%                 + and
     73,443,920  21%           - org-fill-element
     71,424,848  20%            - let
     71,424,848  20%             - unwind-protect
     71,424,848  20%              - progn
     70,403,696  20%               - let
     66,939,368  19%                - save-excursion
     64,924,520  18%                 - org-element-at-point
     63,913,928  18%                  - let
     34,076,928   9%                   - setq
     34,076,928   9%                    - if
     33,458,112   9%                     - condition-case
     30,389,376   8%                      - org-element--parse-to
     30,389,376   8%                       - catch
     29,392,512   8%                        - let
     25,565,952   7%                         - unwind-protect
     25,565,952   7%                          - progn
     24,103,120   6%                           - save-excursion
     20,814,528   6%                            - save-restriction
     15,259,200   4%                             - let*
      6,083,616   1%                              + let
      3,057,120   0%                                and
      2,057,088   0%                                cond
     29,837,000   8%                   + if
      1,036,408   0%                + let*
        213,616   0%       + save-excursion
      9,014,486   2%    + counsel-M-x
        375,920   0%    + previous-line
         28,348   0%    + next-line
          9,984   0%    + org-end-of-line
          6,336   0%    + keyboard-quit
            484   0%    + end-of-buffer
            242   0%    + set-mark-command
     65,166,568  18% - redisplay_internal (C function)
     64,739,756  18%  - jit-lock-function
     64,739,756  18%   - jit-lock-fontify-now
     64,739,756  18%    - jit-lock--run-functions
     64,739,756  18%     - run-hook-wrapped
     64,739,756  18%      - #<compiled 0x19d0e565f4fbf57d>
     64,467,389  18%       - font-lock-fontify-region
     64,467,389  18%        - font-lock-default-fontify-region
     64,466,333  18%         - font-lock-fontify-keywords-region
     64,230,944  18%          + org-activate-links
          8,288   0%          + org-cite-activate
          6,944   0%          + org-raise-scripts
          6,176   0%          + org-fontify-meta-lines-and-blocks
          6,160   0%          + org-activate-dates
          5,440   0%          + org-activate-tags
          5,440   0%          + org-activate-footnote-links
          5,340   0%          + org-fontify-entities
          5,248   0%          + org-fontify-drawers
          5,248   0%          + org-fontify-macros
          5,248   0%          + org-font-lock-add-priority-faces
          5,120   0%          + org-font-lock-add-tag-faces
          5,120   0%          + org-do-emphasis-faces
          5,120   0%          + org-do-latex-and-related
          5,120   0%          + org-activate-code
          1,056   0%         + font-lock-unfontify-region
        254,519   0%       + emojify-redisplay-emojis-in-region
         15,736   0%       + valign-region
        239,728   0%  + eval
        178,900   0%  + #<compiled -0x194fe16722977b6d>
     16,698,568   4% + timer-event-handler
         42,080   0% + emojify-update-visible-emojis-background-after-command
         18,768   0% + winner-save-old-configurations
          3,180   0% + gui-set-selection
          2,154   0% + #<compiled -0x2222a52d2f12599>
              0   0%   ...

#+end_example


[-- Attachment #1.2: Type: text/html, Size: 17508 bytes --]

[-- Attachment #2: Type: text/plain, Size: 282 bytes --]


<#secure method=pgpmime mode=sign>
-- 
[ stardiviner ]
       I try to make every word tell the meaning that I want to express.

       Blog: https://stardiviner.github.io/
       IRC(freenode): stardiviner, Matrix: stardiviner
       GPG: F09F650D7D674819892591401B5DF1C95AE89AC3

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [ISSUE] org-mode fill paragraph is slow and suspend often
  2021-10-26  6:18 [ISSUE] org-mode fill paragraph is slow and suspend often Christopher M. Miles
@ 2021-10-26  8:21 ` Ihor Radchenko
  2021-10-27 14:34   ` Christopher M. Miles
  0 siblings, 1 reply; 5+ messages in thread
From: Ihor Radchenko @ 2021-10-26  8:21 UTC (permalink / raw)
  To: numbchild; +Cc: Org Mode

[-- Attachment #1: Type: text/plain, Size: 552 bytes --]

"Christopher M. Miles" <numbchild@gmail.com> writes:

> Emacs often suspend for a long time.
> ...
>         1467  26%                       - org-element--cache-sync
> ...
>         1334  23%                              - catch
>         1332  23%                               - and
>         1332  23%                                - org-indent-add-properties

Thanks for reporting!
It looks like competing catch..throw.  Both org-indent and org-element
are using `interrupt' signals.

Can you try the attached patch and report back?

Best,
Ihor


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-org-element-cache-Rename-interrupt-org-element-cache.patch --]
[-- Type: text/x-diff, Size: 4808 bytes --]

From cb0a73d58d429b62576822a98235a6bd3ff85809 Mon Sep 17 00:00:00 2001
Message-Id: <cb0a73d58d429b62576822a98235a6bd3ff85809.1635236424.git.yantar92@gmail.com>
From: Ihor Radchenko <yantar92@gmail.com>
Date: Tue, 26 Oct 2021 16:14:40 +0800
Subject: [PATCH] org-element-cache: Rename `interrupt'
 `org-element--cache-interrupt'

* lisp/org-element.el (org-element--cache-sync,
org-element--cache-process-request, org-element--parse-to): Some other
code (at least, `org-indent-mode') is using `interrupt' signal in
`after-change-functions'.  Rename `interrupt' signal used in
org-element-cache to unique `org-element--cache-interrupt'.

Reported in https://list.orgmode.org/PAXPR08MB66400699DACEB31F4F0650F1A3849@PAXPR08MB6640.eurprd08.prod.outlook.com/T/#u
---
 lisp/org-element.el | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/lisp/org-element.el b/lisp/org-element.el
index acc6c56c2..33c7a4051 100644
--- a/lisp/org-element.el
+++ b/lisp/org-element.el
@@ -5818,7 +5818,7 @@ (defun org-element--cache-sync (buffer &optional threshold future-change)
 	  (when org-element--cache-sync-timer
 	    (cancel-timer org-element--cache-sync-timer))
           (let ((time-limit (time-add nil org-element-cache-sync-duration)))
-	    (catch 'interrupt
+	    (catch 'org-element--cache-interrupt
               (when org-element--cache-sync-requests
                 (org-element--cache-log-message "Syncing down to %S-%S" (or future-change threshold) threshold))
 	      (while org-element--cache-sync-requests
@@ -5877,8 +5877,8 @@ (defun org-element--cache-process-request
 not registered yet in the cache are going to happen.  See
 `org-element--cache-submit-request' for more information.
 
-Throw `interrupt' if the process stops before completing the
-request."
+Throw `org-element--cache-interrupt' if the process stops before
+completing the request."
   (org-element--cache-log-message "org-element-cache: Processing request %s up to %S-%S, next: %S"
                        (let ((print-length 10) (print-level 3)) (prin1-to-string request))
                        future-change
@@ -5899,7 +5899,7 @@ (defun org-element--cache-process-request
           (while t
 	    (when (org-element--cache-interrupt-p time-limit)
               (org-element--cache-log-message "Interrupt: time limit")
-	      (throw 'interrupt nil))
+	      (throw 'org-element--cache-interrupt nil))
 	    (let ((request-key (org-element--request-key request))
 		  (end (org-element--request-end request))
 		  (node (org-element--cache-root))
@@ -6012,7 +6012,7 @@ (defun org-element--cache-process-request
       (let ((limit (+ (org-element--request-beg request) (org-element--request-offset request))))
 	(cond ((and threshold (> limit threshold))
                (org-element--cache-log-message "Interrupt: position %d after threshold %d" limit threshold)
-               (throw 'interrupt nil))
+               (throw 'org-element--cache-interrupt nil))
 	      ((and future-change (>= limit future-change))
 	       ;; Changes happened around this element and they will
 	       ;; trigger another phase 1 request.  Skip re-parenting
@@ -6086,7 +6086,7 @@ (defun org-element--cache-process-request
                 (org-element--cache-log-message "Interrupt: %s" (if exit-flag "threshold" "time limit"))
                 (setf (org-element--request-key request) key)
                 (setf (org-element--request-parent request) parent)
-                (throw 'interrupt nil))
+                (throw 'org-element--cache-interrupt nil))
 	      ;; Shift element.
 	      (unless (zerop offset)
                 (when (>= org-element--cache-diagnostics-level 3)
@@ -6207,8 +6207,9 @@ (defun org-element--parse-to (pos &optional syncp time-limit)
 When optional argument SYNCP is non-nil, return the parent of the
 element containing POS instead.  In that case, it is also
 possible to provide TIME-LIMIT, which is a time value specifying
-when the parsing should stop.  The function throws `interrupt' if
-the process stopped before finding the expected result."
+when the parsing should stop.  The function throws
+`org-element--cache-interrupt' if the process stopped before finding
+the expected result."
   (catch 'exit
     (save-match-data
       (org-with-wide-buffer
@@ -6280,7 +6281,7 @@ (defun org-element--parse-to (pos &optional syncp time-limit)
 	       (parent (org-element-property :parent element)))
            (while t
 	     (when (org-element--cache-interrupt-p time-limit)
-               (throw 'interrupt nil))
+               (throw 'org-element--cache-interrupt nil))
              (when (and inhibit-quit org-element--cache-interrupt-C-g quit-flag)
                (when quit-flag
 	         (cl-incf org-element--cache-interrupt-C-g-count)
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [ISSUE] org-mode fill paragraph is slow and suspend often
  2021-10-26  8:21 ` Ihor Radchenko
@ 2021-10-27 14:34   ` Christopher M. Miles
  2021-10-27 15:16     ` Ihor Radchenko
  0 siblings, 1 reply; 5+ messages in thread
From: Christopher M. Miles @ 2021-10-27 14:34 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: Org Mode


[-- Attachment #1.1: Type: text/plain, Size: 215 bytes --]



I applied your patch on the latest pulled org-mode source code. Still can't org-fill elements
quickly when region select text contains org headlines, properties drawer etc.

If I only fill paragraph, it is fine.


[-- Attachment #1.2: Type: text/html, Size: 230 bytes --]

[-- Attachment #2: Type: text/plain, Size: 282 bytes --]


<#secure method=pgpmime mode=sign>
-- 
[ stardiviner ]
       I try to make every word tell the meaning that I want to express.

       Blog: https://stardiviner.github.io/
       IRC(freenode): stardiviner, Matrix: stardiviner
       GPG: F09F650D7D674819892591401B5DF1C95AE89AC3

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [ISSUE] org-mode fill paragraph is slow and suspend often
  2021-10-27 14:34   ` Christopher M. Miles
@ 2021-10-27 15:16     ` Ihor Radchenko
  2021-10-28  3:23       ` [SOLVED] " Christopher M. Miles
  0 siblings, 1 reply; 5+ messages in thread
From: Ihor Radchenko @ 2021-10-27 15:16 UTC (permalink / raw)
  To: Christopher M. Miles; +Cc: Org Mode

"Christopher M. Miles" <numbchild@gmail.com> writes:

> I applied your patch on the latest pulled org-mode source code. Still can't org-fill elements
> quickly when region select text contains org headlines, properties drawer etc.
>
> If I only fill paragraph, it is fine.

Thanks for the pointer. I now managed to reproduce the problem. It was
an infinite loop in org--backward-paragraph-once. Fixed on main via
cc3df3af2.

Best,
Ihor


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [SOLVED] Re: [ISSUE] org-mode fill paragraph is slow and suspend often
  2021-10-27 15:16     ` Ihor Radchenko
@ 2021-10-28  3:23       ` Christopher M. Miles
  0 siblings, 0 replies; 5+ messages in thread
From: Christopher M. Miles @ 2021-10-28  3:23 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: Org Mode


[-- Attachment #1.1: Type: text/plain, Size: 531 bytes --]



Thanks, confirmed solved.

Ihor Radchenko <yantar92@gmail.com> writes:

> "Christopher M. Miles" <numbchild@gmail.com> writes:
>
>> I applied your patch on the latest pulled org-mode source code. Still can't org-fill elements
>> quickly when region select text contains org headlines, properties drawer etc.
>>
>> If I only fill paragraph, it is fine.
>
> Thanks for the pointer. I now managed to reproduce the problem. It was
> an infinite loop in org--backward-paragraph-once. Fixed on main via
> cc3df3af2.
>
> Best,
> Ihor



[-- Attachment #1.2: Type: text/html, Size: 926 bytes --]

[-- Attachment #2: Type: text/plain, Size: 282 bytes --]


<#secure method=pgpmime mode=sign>
-- 
[ stardiviner ]
       I try to make every word tell the meaning that I want to express.

       Blog: https://stardiviner.github.io/
       IRC(freenode): stardiviner, Matrix: stardiviner
       GPG: F09F650D7D674819892591401B5DF1C95AE89AC3

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-10-28  3:32 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-10-26  6:18 [ISSUE] org-mode fill paragraph is slow and suspend often Christopher M. Miles
2021-10-26  8:21 ` Ihor Radchenko
2021-10-27 14:34   ` Christopher M. Miles
2021-10-27 15:16     ` Ihor Radchenko
2021-10-28  3:23       ` [SOLVED] " Christopher M. Miles

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).