emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Re: tangle option to not write a file with same contents?


From: Ihor Radchenko
Subject: [PATCH] Re: tangle option to not write a file with same contents?
Date: Sun, 08 May 2022 12:42:53 +0800

Max Nikulin <manikulin@gmail.com> writes:

> On 28/10/2021 11:04, Greg Minshall wrote:
>> 
>> i wonder if it would be reasonable to add an option such that, when
>> tangling, `org-babel-tangle` would not write a file with the
>> already-existing contents of the target file?
>> 
>> this would be helpful, e.g., for those of us who use make(1)-based work
>> flows.
>
> It was not obvious for me earlier that it should be namely an *option*, 
> not just change of behavior, since e.g. `org-babel-load-file' relies on 
> timestamp comparison of the source .org file and the derived .el file. I 
> am unsure concerning default value of such setting.

I agree that it should be the default behaviour.
The patch is attached.

On SSD, when tangling into ~200 files, the patch speeds up tangling
by almost 2x: before 7.6 sec; after 4.4 sec.

Best,
Ihor

>From 68d90e73da17e423220211897ad1e86a4eb2e5a1 Mon Sep 17 00:00:00 2001
Message-Id: 
<68d90e73da17e423220211897ad1e86a4eb2e5a1.1651984776.git.yantar92@gmail.com>
From: Ihor Radchenko <yantar92@gmail.com>
Date: Sun, 8 May 2022 12:32:40 +0800
Subject: [PATCH] org-tangle: Do not overwrite when contents does not change

* lisp/ob-tangle.el (org-babel-tangle): Do not overwrite existing
tangled files if their contents is exactly the same as we are going to
write during tangle process.  This avoids unneeded disk writes and can
speed up tangling significantly when many small files are tangles from
a single .org source.

An example of performance improvement when tangling an .org file into
~200 files:
(benchmark-run 10 (org-babel-tangle))
Before the commit (on SSD): (76.33826743 8 11.551725374)
After the commit:           (43.628606052 4 5.751274237)
---
 lisp/ob-tangle.el | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/lisp/ob-tangle.el b/lisp/ob-tangle.el
index 16d938afb..c011bf662 100644
--- a/lisp/ob-tangle.el
+++ b/lisp/ob-tangle.el
@@ -282,11 +282,17 @@ (defun org-babel-tangle (&optional arg target-file 
lang-re)
                    lspecs)
                   (when make-dir
                     (make-directory fnd 'parents))
-                   ;; erase previous file
-                   (when (file-exists-p file-name)
-                     (delete-file file-name))
-                  (write-region nil nil file-name)
-                  (mapc (lambda (mode) (set-file-modes file-name mode)) modes)
+                   (unless
+                       (let ((new-contents-hash (buffer-hash)))
+                         (with-temp-buffer
+                           (when (file-exists-p file-name)
+                             (insert-file-contents file-name))
+                           (equal (buffer-hash) new-contents-hash)))
+                     ;; erase previous file
+                     (when (file-exists-p file-name)
+                       (delete-file file-name))
+                    (write-region nil nil file-name)
+                    (mapc (lambda (mode) (set-file-modes file-name mode)) 
modes))
                    (push file-name path-collector))))))
         (if (equal arg '(4))
             (org-babel-tangle-single-block 1 t)
-- 
2.35.1


reply via email to

[Prev in Thread] Current Thread [Next in Thread]