this post was submitted on 30 Oct 2023
0 points (50.0% liked)

Emacs

305 readers
1 users here now

A community for the timeless and infinitely powerful editor. Want to see what Emacs is capable of?!

Get Emacs

Rules

  1. Posts should be emacs related
  2. Be kind please
  3. Yes, we already know: Google results for "emacs" and "vi" link to each other. We good.

Emacs Resources

Emacs Tutorials

Useful Emacs configuration files and distributions

Quick pain-saver tip

founded 1 year ago
MODERATORS
 

I've been looking for methods to improve Emacs performance especially with my configuration being over >3k. I'm not particularly interested in startup-time since I never close Emacs. Here's what I found so far

(setq package-native-compile                            t
      gcmh-high-cons-threshold                          100000000
      gc-cons-threshold                                 100000000
      scroll-conservatively                             101
      jit-lock-defer-time                               0
      large-file-warning-threshold                      nil)



(add-hook 'after-init-hook #'(lambda () (setq gc-cons-threshold (* 100 1000 1000))))
(defvar gc-timer nil)
(defun salih/maybe-gc ()
  (let ((original gc-cons-threshold))
    (setq gc-cons-threshold 800000)
    (setq gc-cons-threshold original
          gc-timer (run-with-timer 2 nil #'salih/schedule-maybe-gc))))

(defun salih/schedule-maybe-gc ()
  (setq gc-timer (run-with-idle-timer 2 nil #'salih/maybe-gc)))

(salih/schedule-maybe-gc)

I can tell that I've noticed some improvements.

top 26 comments
sorted by: hot top controversial new old
[–] [email protected] 2 points 10 months ago

If not in startup, what performance deficits and improvements have you noticed? How do you measure or notice the improvements?

[–] [email protected] 2 points 10 months ago

Define fast. Speed is relative. Your fast and my fast may not be the same. But my answer is lazy load everything.

[–] [email protected] 2 points 10 months ago

> I can tell that I've noticed some improvements.

I can tell this claim is worthless without data.

[–] [email protected] 1 points 10 months ago

Build emacs yourself and enable the option for natively compiling the lisp to bytecode

[–] [email protected] 1 points 10 months ago

I had the package yascroll active, and it was fine on most files but org-mode was quite slow. I disabled that as well as svg-tag-mode etc

[–] [email protected] 1 points 10 months ago (1 children)
  1. use a POSIX OS (i.e., linux, unix, or macOS) as their file system and I/O management are generally more performant than Windows. NOTE: macOS I/O is worse than linux/unix, but better than windows; and their ARM chips generally perform better in their OS as well.

  2. I use 29.1 with native compilation enabled, and I generally use the Full Ahead of Time compile when i can, so that all the built-in/included by default emacs code is already compiled.

  3. I use a lot of tricks from DOOM Emacs, its hard to list them all, but many of them are good. Take a look at their early-init.el, init.el, and core files to see what they do to speed things up in various cases.

  4. I used Elpaca over straight/use-package for package management, as it was designed to be async from the ground up, so it can do a lot in parallel, well, emacs version of parallel.

  5. I use a lot of built-in hooks, package-hooks, and custom-hooks, to only load packages when they are actually needed, and try to avoid global modes when possible.

my config is a bit of a mess, but if you are curious, you can see it here:

customacs

[–] [email protected] 1 points 10 months ago (1 children)

Also if you need to use windows, I found out recently that even GUI apps can be run under WSL. That seems to help the speed problem (I only tried magit and basic file handling and it is much closer to the speed under Linux)

[–] [email protected] 1 points 10 months ago

yes, definitely use WSL if you are on windows! Emacs goes from useable, to very performant when you setup WSL for GUI :)

[–] [email protected] 1 points 10 months ago

Upgraded to 29.1

[–] [email protected] 1 points 10 months ago

I’m sure there is a way to do this in vanilla but doom emacs cli lets you compile so I will compile all the packages with that

[–] [email protected] 1 points 10 months ago (1 children)

(advice-add 'jsonrpc--log-event :override #'ignore)

[–] [email protected] 2 points 10 months ago

Can you say what's going on here?

I'm assuming it's avoiding doing work, but from which package? Something in core Emacs?

[–] [email protected] 1 points 10 months ago

Doom Emacs has great optimizations for this.

You should manage your packages and defer those that are not immediately necessary (using use-package options and consider using benchmark to control initialization time).

If you truly want to achieve blazing speed, consider running Emacs as a daemon (Emacs Daemon).

[–] [email protected] 1 points 10 months ago (1 children)

I've focused on what I really need and avoid cluttering my config. I've spent considerable time understanding what performs well and what doesn't. I try to minimize the use of global modes and refrain from installing additional packages if built-in ones do the job. I'm very discerning when it comes to choosing any new package. Essentially, I have to "sell" myself on a new package, if you know what I mean. Yes, I do use byte-compilation for Lisp code and feel that I've managed to make things quite efficient and clean. You can take a look and borrow any solutions from my setup here: https://github.com/sergeyklay/.emacs.d

[–] [email protected] 1 points 10 months ago

With the new --init-directory switch of Emacs 29, you can define a completely separate environment for Emacs that could be used to make more mean, lean and specialized versions of Emacs. For example, instead of having your Emacs do everything, IRC, email, programming, Org mode stuff etc. etc. etc. you could have a shell command invoking each one, e.g. Eirc, Eemail, Eorg, etc.

[–] [email protected] 1 points 10 months ago

LSP-mode: By following instructions here: https://emacs-lsp.github.io/lsp-mode/page/performance/

For the rest: M-x profiler-start, Mx profiler-stop, then M-x profiler-report.

[–] [email protected] 1 points 10 months ago

Have a look at Emacs client/server mode.
It creates a single hidden instance of Emacs, and lets all other emacs windows connect to it.

You can start the server with your computer start up, and then opening clients is instant.

[–] [email protected] 1 points 10 months ago

For me, the main issue was startup speed from my customizations. This I sped up by:

  • Making use of emacsclient over new emacs sessions.
  • Combining scattered customization files into a single large emacs.el file.
  • Use defvar and autoload over require, load, eval-after-load.

The last one is mostly to allow compiler- and flycheck warnings to work, without prematurely loading dependencies of my customization code.

[–] [email protected] 1 points 10 months ago

Buy a good cpu

[–] [email protected] 1 points 10 months ago

If you want to improve the bootup performance, you can use the Client/Server feature that Emacs provides. It can utilize it to significantly speed up your Emacs.

Run the Emacs server by:

emacs --daemon

And Emacs client connects to it automatically:

emacsclient sample.cpp
[–] [email protected] 1 points 10 months ago

- Get better hardware if you are still on old hardware 5 or more years ago. A budget $300 - $500 PC with modern CPUs and a decent SSD will be significant faster than whatever 5 years ago.

- If you're on Windows, compiled your own Emacs, then compile every packages (built-in or 3rd party) with native-comp. Here's a guide: https://www.reddit.com/r/emacs/comments/131354i/guide_compile_your_own_emacs_to_make_it_really/

- ???

- Enjoy!

[–] [email protected] 1 points 10 months ago

switch to neovim

[–] [email protected] 1 points 10 months ago

Improve the performance of what?

[–] [email protected] 1 points 10 months ago

I can tell that I've noticed some improvements.

I guess you haven't run your Emacs for a long time, because ~100 megabytes of allocated memory will take its time to GC check. With that amount of RAM, you will probably notice Emacs "stuttering", like freezing for small periods of time when using it normally. The bigger the gc-cons-threshold value, the longer time it will take for GC to check the memory. Emacs does not have an incremental and multithreaded GC, so your Emacs will appear as frozen to you.

(defun salih/maybe-gc ()
  (let ((original gc-cons-threshold))
    (setq gc-cons-threshold 800000)
    (setq gc-cons-threshold original
          gc-timer (run-with-timer 2 nil #'salih/schedule-maybe-gc))))

Have you even looked at gc-cons-threshold value; after your idle timer has finished the work? Looking at your code, I believe you will be surprised because it does not seem to be what you think it will be.

What is the point of the first setq there?

In the third line, you are setting the value to hardcoded ~800 kb (I think it is the on 64-bit systems, but it is not so important), just to immediately override it with 100 meg as you defined it in the previous code piece (third line of your code), one after the gcmh. Secondly, what is the reason to use gcmh package if you are going to do it all manually :). GCMH will do exactly the same thing you are doing manually in that example if I am not mistaken; I don't use that package myself, but someone wrote it for the purpose of automating that little hack you are trying to make there. IMO, either use that package and be happy, or do it all manually.

What is the purpose of setq-ing gc-timer to run your function in that let-body (last line) which appears to just do exactly the same - you are again doing the same thing in your salih/schedule-maybe-gc. You are just telling Emacs in an infinite loop to set up a new timer when it is idle. If you believe you are telling Emacs to actually garbage collect something, you are wrong; you are just setting up another timer.

In other words; your code does not do what you believe it does; it is rather plain wrong, in other words, buggy, to put it mildly.

I can tell that I've noticed some improvements.

I can tell you haven't, you just don't know about it. When other posters here told you to benchmark they were correct.

we are not in an academic seminar, such anecdotal statements should be authentic enough.

We don't benchmark because of being academics, but because of ourselves. If we won't to improve something in whatever terms, cpu execution time, memory usage, number of resources allocated (timers, files, sockets etc.) you have to measure. You can't know for sure if you don't measure, there is no way. Your computer can be doing stuff, your application can be doing stuff, and so on. Modern computer systems are not deterministic in terms that hardware usage being exactly the same each time you run an application. Execution time is highly dependent on your OS and CPU scheduler(s), memory usage patterns and so on, some of the things your application usually does not influence explicitly.

Without measuring you are walking with a blindfold. However, you seem to have other problems than just benchmarking your stuff; you should really read the manual about stuff you are trying to improve or change, use built-in help; C-h f/v to see what stuff does and try to understand it. Read whichever blog posts you have found again and reflect carefully on what they say and why. Just blindly copying stuff without understanding it results in stuff like your code above.

Finally, to answer your original question, it all depends on how you wish to use your Emacs. What might be fast for one usage pattern, might not be fast for another one. Again, you will have to know what you are doing and to measure for your particular use-case.

[–] [email protected] 1 points 10 months ago
[–] [email protected] 0 points 10 months ago

switched to vim