emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* [PATCH] org-table-to-lisp enhanced
@ 2024-02-25 10:40 tbanelwebmin
  2024-02-25 11:41 ` Ihor Radchenko
  0 siblings, 1 reply; 2+ messages in thread
From: tbanelwebmin @ 2024-02-25 10:40 UTC (permalink / raw)
  To: emacs-orgmode

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

Here is a new version of `org-table-to-lisp'. Why a new version?

- Because it is more than 3x faster than the current one.
   Bench-marked on a 3822 rows by 16 columns Org table
   - current: 0.405 seconds
   - new one: 0.122 seconds
   on Emacs 30.0.50 with native compilation
   The speedup is achieved with or without native compilation.

- Because it does not use regexps anymore.
   It uses `following-char'
   instead of `re-search-forward'
   Therefore the global regexp state is no longer clobbered.

- Because after a 120x speedup in May 2020
   (by Nicolas Goaziou and myself)
   it is funny to discover yet another way to a 3x speedup.

- Because org-table-to-lisp is a basic
   building block of Org Mode, used in
   - table alignment
   - table export
   - Babel
   - plotting
   - table transposition

- Because this version is a drop-in replacement.
   The overall algorithm does not changed.

I ran all the standard unit tests of Org Mode as of [2024-02-24]. All 
went as expected.

Have fun
Thierry

[-- Attachment #2: 0001-org-table.el-Enhanced-table-parsing.patch --]
[-- Type: text/x-patch, Size: 2972 bytes --]

From 21b3e325e73d4a7332631eeed93cb2a025e024fd Mon Sep 17 00:00:00 2001
From: Thierry Banel <tbanelwebmin@free.fr>
Date: Sat, 24 Feb 2024 17:31:46 +0100
Subject: [PATCH] org-table.el: Enhanced table parsing

* lisp/org-table.el (org-table-to-lisp): Refactored.
* etc/ORG-NEWS: Document changes.

`org-table-to-lisp' is significantly faster.
It no longer uses regexps, nor clobbers the global regexp state.
---
 etc/ORG-NEWS      |  6 ++++++
 lisp/org-table.el | 37 ++++++++++++++++++++++++-------------
 2 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index b79f275c4..a40a0f226 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -1275,6 +1275,12 @@ For symmetry with =\S= and =\sect= for the section symbol, =\P= has
 been added as an another form for the pilcrow symbol currently
 available as =\para=.
 
+*** ~org-table-to-lisp~ no longer clobbers the regexp global state
+
+It does no longer use regexps.
+
+It is also faster. Large tables can be read quickly.
+
 * Version 9.6
 
 ** Important announcements and breaking changes
diff --git a/lisp/org-table.el b/lisp/org-table.el
index c6e16c1fd..67fffc23e 100644
--- a/lisp/org-table.el
+++ b/lisp/org-table.el
@@ -5494,25 +5494,36 @@ for a horizontal separator line, or a list of field values as strings.
 The table is taken from the parameter TXT, or from the buffer at point."
   (if txt
       (with-temp-buffer
+	(buffer-disable-undo)
         (insert txt)
         (goto-char (point-min))
         (org-table-to-lisp))
     (save-excursion
       (goto-char (org-table-begin))
-      (let ((table nil))
-        (while (re-search-forward "\\=[ \t]*|" nil t)
-	  (let ((row nil))
-	    (if (looking-at "-")
-		(push 'hline table)
-	      (while (not (progn (skip-chars-forward " \t") (eolp)))
-		(push (buffer-substring
-		       (point)
-		       (progn (re-search-forward "[ \t]*\\(|\\|$\\)")
-			      (match-beginning 0)))
-		      row))
-	      (push (nreverse row) table)))
+      (let (table)
+        (while (progn (skip-chars-forward " \t")
+                      (eq (following-char) ?|))
+	  (forward-char)
+	  (push
+	   (if (eq (following-char) ?-)
+	       'hline
+	     (let (row)
+	       (while (progn
+                        (skip-chars-forward " \t")
+                        (not (eolp)))
+                 (let ((q (point)))
+                   (skip-chars-forward "^|\n")
+                   (goto-char
+                    (prog1
+                        (let ((p (point)))
+                          (unless (eolp) (setq p (1+ p)))
+                          p)
+	              (skip-chars-backward " \t" q)
+	              (push (buffer-substring-no-properties q (point)) row)))))
+	       (nreverse row)))
+	   table)
 	  (forward-line))
-        (nreverse table)))))
+	(nreverse table)))))
 
 (defun org-table-collapse-header (table &optional separator max-header-lines)
   "Collapse the lines before `hline' into a single header.
-- 
2.34.1


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

* Re: [PATCH] org-table-to-lisp enhanced
  2024-02-25 10:40 [PATCH] org-table-to-lisp enhanced tbanelwebmin
@ 2024-02-25 11:41 ` Ihor Radchenko
  0 siblings, 0 replies; 2+ messages in thread
From: Ihor Radchenko @ 2024-02-25 11:41 UTC (permalink / raw)
  To: tbanelwebmin; +Cc: emacs-orgmode

tbanelwebmin <tbanelwebmin@free.fr> writes:

> Here is a new version of `org-table-to-lisp'. Why a new version?
> ...
> I ran all the standard unit tests of Org Mode as of [2024-02-24]. All 
> went as expected.

Thanks!
Applied, onto main.
https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/?id=407a55c1c

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


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

end of thread, other threads:[~2024-02-25 11:38 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-25 10:40 [PATCH] org-table-to-lisp enhanced tbanelwebmin
2024-02-25 11:41 ` Ihor Radchenko

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