Subject: bug#59692: 29.0.60; Reduce installation size by disabling byte-compilation for some lisp files that won't benefit

From: daanturo <[email-masked]>
Date: Thu, 1 Dec 2022 01:58:45 +0700

> measurements of code speed with and without byte-compilation

I tried to evaluate performance different:

### Load time

Helper macro:
```emacs-lisp
(defmacro my-with-deferred-gc (&rest body)
  `(dlet ((gc-cons-threshold most-positive-fixnum) (gc-cons-percentage 0.75))
     ,@body))
```

(Each of those measures was executed in a new Emacs instance, as the
second `load` is (for me) cheaper than the first `load`).

#### lisp/leim/ja-dic

(my-with-deferred-gc (benchmark-progn (load
"/usr/share/emacs/29.0.60/lisp/leim/ja-dic/ja-dic")))

> .el:
Loading /usr/share/emacs/29.0.60/lisp/leim/ja-dic/ja-dic.el (source)...done
Elapsed time: 0.707891s
> .elc:
Loading /usr/share/emacs/29.0.60/lisp/leim/ja-dic/ja-dic...done
Elapsed time: 0.104832s
> .eln:
Loading /usr/share/emacs/29.0.60/lisp/leim/ja-dic/ja-dic (native compiled elisp)...done
Elapsed time: 0.104676s

#### Other auto-generated lisp files in lisp/leim/quail, all of them are
Chinese at the moment, the largests being ZIRANMA.el, ARRAY30.el:

(my-with-deferred-gc (benchmark-progn (load
"/usr/share/emacs/29.0.60/lisp/leim/quail/ZIRANMA")))

> .el:
Loading /usr/share/emacs/29.0.60/lisp/leim/quail/ZIRANMA.el (source)...done
Elapsed time: 0.037230s
> .elc:
Loading /usr/share/emacs/29.0.60/lisp/leim/quail/ZIRANMA...done
Elapsed time: 0.058042s
> .eln:
Loading /usr/share/emacs/29.0.60/lisp/leim/quail/ZIRANMA (native compiled elisp)...
Elapsed time: 0.062904s

(my-with-deferred-gc (benchmark-progn (load
"/usr/share/emacs/29.0.60/lisp/leim/quail/ARRAY30")))

> .el
Loading /usr/share/emacs/29.0.60/lisp/leim/quail/ARRAY30.el (source)...done
Elapsed time: 0.031518s
> .elc
Loading /usr/share/emacs/29.0.60/lisp/leim/quail/ARRAY30...done
Elapsed time: 0.037412s
> .eln
Loading /usr/share/emacs/29.0.60/lisp/leim/quail/ARRAY30 (native compiled elisp)...done
Elapsed time: 0.041110s

(my-with-deferred-gc (benchmark-progn (load
"/usr/share/emacs/29.0.60/lisp/leim/quail/QJ")))
> .el
Loading /usr/share/emacs/29.0.60/lisp/leim/quail/QJ.el (source)...done
Elapsed time: 0.001649s
> .elc
Loading /usr/share/emacs/29.0.60/lisp/leim/quail/QJ...done
Elapsed time: 0.004481s
> .eln
Loading /usr/share/emacs/29.0.60/lisp/leim/quail/QJ (native compiled elisp)...done
Elapsed time: 0.005001s

For "ja-dic.el", byte-compilation clearly helped speedup loading. But
native-compilation doesn't offer any more significantly. As I inspect
"ja-dic.elc", byte-compilation did by expanding macros to
`(defconst var literal-list)` forms, I think that native compilation
won't offer more about run time performance.

For auto-generated files under lisp/leim/quail (ZIRANMA, ARRAY30, QJ
tested above), sometimes compilation even slows down the loading process
compared to just interpretation.

About the run time performance, since I don't know Chinese, I will
approximately benchmark lisp/leim/quail/vnvni.el (Vietnamese) instead as
this file is quite similar to ZIRANMA.el: both has only 2 forms --
(quail-define-package ...) and (quail-define-rules ...).

ydotool is used (https://github.com/ReimuNotMoe/ydotool) to perform
auto-typing as in bench-quail.el attached. The function to be
benchmarked is #'quail-input-method.

emacs -q -l bench-quail.el --eval "(progn (my-to-new-buffer) (my-benchmark-quail nil))"
emacs -q -l bench-quail.el --eval "(progn (my-to-new-buffer) (my-benchmark-quail 'compiled))"

Benchmarking results: (note that :num means the total key pressed by ydotool).

Loading /usr/share/emacs/29.0.60/lisp/leim/quail/vnvni.el (source)...done
Elapsed time: 0.016844s (0.008795s in 1 GCs)
(:compiled nil (:num 145 :total-time 2.118776153 :average 0.014612249331034484))

Loading /usr/share/emacs/29.0.60/lisp/leim/quail/vnvni (native compiled elisp)...done
Elapsed time: 0.034253s (0.009630s in 1 GCs)
(:compiled compiled (:num 145 :total-time 2.117245182999999 :average 0.014601690917241374))

So I conclude that those quail lisp package files' compilation statuses,
whether compiled or not, doesn't affect run-time performance at all.

### lisp/international/titdic-cnv.el's pinyin-convert

It produce a single form: (defconst var literal-list) so the
corresponding produced ".elc" file is just the same with new lines
joined. Also the times taken to load lisp/language/pinyin.elc and
/lisp/language/pinyin.el aren't different anyway.

### About the patch

In the patch below, I disabled native-compile for "ja-dic" while keeping
byte-compile (by modifying `generate-lisp-file-trailer` keyword args),
and disable compilation altogether for files produced by titdic-convert,
miscdic-convert, pinyin-convert. There's no new .dir-locals files
introduced like the previous patch.

> Disk space is cheap these days.

But it's always better to be light if we don't suffer any penalties. A
little number of megabytes saved will always be appreciated by people
with metered connection and/or limited bandwidth, or people who have
multiple versions of Emacs installed. Disk space is indeed becoming
cheaper, but with varying pace among countries. I am currently using a
laptop which only has 238GiB & un-expandable, that explains my joy when
pacman shows net upgrade size being negative during system updates.

Thanks to the patch, I saved 20.20 MiB by a couple of flag flips without
making any new files. Please consider again if you think it makes more
sense than my previous justifications, thank you.

-- 
Daanturo.
From 1ccf494d4175f8c56ef95a0661249f42337fae77 Mon Sep 17 00:00:00 2001
From: Daanturo <[email-masked]>
Date: Wed, 30 Nov 2022 16:03:59 +0700
Subject: [PATCH] Inhibit compilation for some quail packages generators

---
 lisp/international/ja-dic-cnv.el | 3 ++-
 lisp/international/titdic-cnv.el | 6 +++---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/lisp/international/ja-dic-cnv.el b/lisp/international/ja-dic-cnv.el
index ec68d8c804..df70959b19 100644
--- a/lisp/international/ja-dic-cnv.el
+++ b/lisp/international/ja-dic-cnv.el
@@ -396,7 +396,8 @@ skkdic-convert
 	;; Postfix
 	(with-current-buffer buf
 	  (goto-char (point-max))
-          (generate-lisp-file-trailer ja-dic-filename :compile t)))
+          (generate-lisp-file-trailer
+           ja-dic-filename :compile t :inhibit-native-compile t)))
 
       ;; Save the working buffer.
       (set-buffer buf)
diff --git a/lisp/international/titdic-cnv.el b/lisp/international/titdic-cnv.el
index b942f5fabc..8996214dcb 100644
--- a/lisp/international/titdic-cnv.el
+++ b/lisp/international/titdic-cnv.el
@@ -527,7 +527,7 @@ titdic-convert
 	  ;; Process the body part
 	  (tit-process-body)
           (generate-lisp-file-trailer
-           filename :inhibit-provide t :compile t :coding nil))))))
+           filename :inhibit-provide t :compile nil :coding nil))))))
 
 ;;;###autoload
 (defun batch-titdic-convert (&optional force)
@@ -1161,7 +1161,7 @@ miscdic-convert
                 (with-current-buffer dstbuf
                   (funcall converter dicbuf)))))
           (generate-lisp-file-trailer
-           quailfile :inhibit-provide t :compile t :coding nil)))
+           quailfile :inhibit-provide t :compile nil :coding nil)))
       (setq tail (cdr tail)))))
 
 (defun batch-miscdic-convert ()
@@ -1218,7 +1218,7 @@ pinyin-convert
           (forward-line 1)))
       (insert ")\n\"An alist holding correspondences between pinyin syllables\
  and\nChinese characters.\")\n\n")
-      (generate-lisp-file-trailer dst-file :compile t))
+      (generate-lisp-file-trailer dst-file :compile nil))
     (kill-emacs 0)))
 
 ;;; titdic-cnv.el ends here
-- 
2.38.1