@@ -749,6 +749,14 @@ When ASSOCIATED is `all', unregister CONTAINER everywhere."
749749 (remove container (plist-get collection :container )))
750750 (org-persist--add-to-index collection))))))
751751
752+ (defvar org-persist--read-cache (make-hash-table :test #'equal )
753+ " Hash table storing as-read data object hashes.
754+
755+ This data is used to avoid overwriting unchanged data." )
756+ (defvar org-persist--write-cache (make-hash-table :test #'equal )
757+ " Hash table storing as-written data objects.
758+
759+ This data is used to avoid reading the data multiple times." )
752760(defun org-persist-read (container &optional associated hash-must-match load? )
753761 " Restore CONTAINER data for ASSOCIATED.
754762When HASH-MUST-MATCH is non-nil, do not restore data if hash for
@@ -783,15 +791,18 @@ When LOAD? is non-nil, load the data instead of reading."
783791 (unless (seq-find (lambda (v )
784792 (run-hook-with-args-until-success 'org-persist-before-read-hook v associated))
785793 (plist-get collection :container ))
786- (setq data (org-persist--read-elisp-file persist-file))
787- (cl-loop for container in (plist-get collection :container )
788- with result = nil
789- do
790- (if load?
791- (push (org-persist-load:generic container (alist-get container data nil nil #'equal ) collection) result)
792- (push (org-persist-read:generic container (alist-get container data nil nil #'equal ) collection) result))
793- (run-hook-with-args 'org-persist-after-read-hook container associated)
794- finally return (if (= 1 (length result)) (car result) result)))))))
794+ (setq data (or (gethash persist-file org-persist--write-cache)
795+ (org-persist--read-elisp-file persist-file)))
796+ (puthash persist-file (sxhash-equal data) org-persist--read-cache)
797+ (when data
798+ (cl-loop for container in (plist-get collection :container )
799+ with result = nil
800+ do
801+ (if load?
802+ (push (org-persist-load:generic container (alist-get container data nil nil #'equal ) collection) result)
803+ (push (org-persist-read:generic container (alist-get container data nil nil #'equal ) collection) result))
804+ (run-hook-with-args 'org-persist-after-read-hook container associated)
805+ finally return (if (= 1 (length result)) (car result) result))))))))
795806
796807(defun org-persist-load (container &optional associated hash-must-match )
797808 " Load CONTAINER data for ASSOCIATED.
@@ -847,7 +858,9 @@ When IGNORE-RETURN is non-nil, just return t on success without calling
847858 (let ((file (org-file-name-concat org-persist-directory (plist-get collection :persist-file )))
848859 (data (mapcar (lambda (c ) (cons c (org-persist-write:generic c collection)))
849860 (plist-get collection :container ))))
850- (org-persist--write-elisp-file file data)
861+ (puthash file data org-persist--write-cache)
862+ (unless (equal (sxhash-equal data) (gethash file org-persist--read-cache))
863+ (org-persist--write-elisp-file file data))
851864 (or ignore-return (org-persist-read container associated))))))))
852865
853866(defun org-persist-write-all (&optional associated )
0 commit comments