Live data from Hacker News

Bringing GNU Emacs to Native Code (2020)

arxiv.org

121–130 of 138 posts

Re: Bringing GNU Emacs to Native Code (2020)

#121

The speedup is very noticeable. Like others I'm running the "native-comp" branch of Emacs, since months, without any issue. It's now been merged into trunk and it's going to be the default: https://news.ycombinator.com/item?id=26935401 The only drawback I saw is that compiling Emacs itself takes 3x to 4x longer when compiling the native-comp branch.

Eh, I don't know... I suspect the speed up depends a lot on how a person uses Emacs. I've been using it for a few months as well, and I haven't noticed any change. My start up time, as measured with 'emacs-init-time, is 0.6-0.7 seconds instead of 0.7-0.8, but that's about all I've noticed, and there hasn't been any difference in day-to-day editting. I haven't had any problems, so that's good at least.

i also don't notice any speedup. it was a bit disappointing :)

i use gnus and org-mode heavily. 80% of my day is in one or the other.

i would add that emacs28 w/o compilation feels faster than emacs27.

emacs28 w and wo compilation feel the same.

Re: Bringing GNU Emacs to Native Code (2020)

#122
post #115

It makes LSPs usable for me on my desktop 5950x. Still a bit laggy on my laptop.

Unfortunately, Emacs won't really benefit since it is a (mostly) single-threaded application by design. But that sweet 5950x should definitely speed up running dozens of language servers and indexers at the same time :-D

Yes it’s a shame. I really like emacs but the lagginess is just too jarring while working.

Re: Bringing GNU Emacs to Native Code (2020)

#123
post #110

Earlier quoted context omitted.

vscode doesn't even support multiple monitors, it's far behind in many areas.

What does it mean for an editor to "support multiple monitors?"

Emacs allows you to open multiple windows that share the same local server / process and essentially work as one editor.

You can open the same or different files in the different views, use one of the views for debugging, shells, remotely running tests, while you use the other views for other stuff (showing different files side-by-side, etc.).

I often see vim and vs code users doing a lot of shuffling around when working with multiple open files to switch back and forth between files or across tabs, but with emacs none of this is really necessary.

Re: Bringing GNU Emacs to Native Code (2020)

#124

Earlier quoted context omitted.

> but once you activated all the quality-of-life features and added a bunch of third-party packages, there was a noticeable performance impact. I'm not sure I understand what you mean there. Unless those third-party packages are scheduling tasks on the event loop then they should not be impacting performance of your other operations. Just having lots of things installed and activated doesn't affect performance.

It's not having lots of things installed. It's actually using them. Basically how much custom elisp is running in your buffer.

With respect, I think you're confused. But even if I'm right, that's OK, software is complicated, and it took me a while to get these things straight.

Multiple installed emacs packages do not execute their code simultaneously unless they are using something like run-with-timer to schedule tasks on the event loop. Can you give me an example of an emacs package that causes custom elisp to be "running in your buffer" continuously?

For example, org-mode does many complicated things, but only when you ask it to -- i.e. when you issue one of its keybindings, or call one of its functions. Then, you enter a blocking ("synchronous") function call: the main thread is executing the org-mode code and nothing else until it's done. So, if things happen as I'm describing, you can see that it doesn't matter how many packages you have installed: only one of them is taxing the CPU at any one time, and they are not all queuing up work and causing the event loop to get bogged down.

Similarly, swiper, ivy, counsel, magit -- they only do things when you ask them to.

To put this another way: in general, your installed packages are not active simultaneously. Therefore, the performance of your editing operations is not affected by how many packages you use.

Re: Bringing GNU Emacs to Native Code (2020)

#125

Earlier quoted context omitted.

It's not having lots of things installed. It's actually using them. Basically how much custom elisp is running in your buffer.

With respect, I think you're confused. But even if I'm right, that's OK, software is complicated, and it took me a while to get these things straight. Multiple installed emacs packages do not execute their code simultaneously unless they are using something like run-with-timer to schedule tasks on the event loop. Can you give me an example of an emacs package that causes custom elisp to be "running in your buffer" co…

> Multiple installed emacs packages do not execute their code simultaneously unless they are using something like run-with-timer to schedule tasks on the event loop.

It's true that few things run in the background constantly. You can check for that easily, with M-x list-timers. On my work laptop, my most feature-packed Emacs instance, I currently have three timers active (and 11 waiting for a trigger). Those three are:

  Repeat   Function
     5.0   auto-revert-buffers
    60.0   ac-clear-variables-every-minute
  3600.0   url-cookie-write-file
So there's only one frequently updating timer running, that was put there by (I think) lsp-mode.

Of the inactive timers, there are a bunch on a really short trigger - for features like highlighting indentation guides, highlighting parentheses, etc. But these are the ones that wake up when you do just about anything in a relevant buffer - along with various hooks being fired.

Because it's the hooks that seem to be missing in your current understanding.

I just switched to a random buffer, and in it, I have 18 functions in post-command-hook, and 2 functions in post-self-insert-hook. That's 20 functions to execute on pretty much every single key press, and all of them come from optional features, both built-in and from additional packages. Syntax highlighting (font-lock-mode), error checking (flycheck), documentation helpers (eldoc), LSP stuff, snippet expansion, etc.

All these functions are usually fast (plenty of them just reschedule aforementioned inactive timers), but every now and then, one of them gets some heavier workload. And you notice a stutter. Perhaps inserting a character took more milliseconds than you're used to, because it caused font-lock to re-render the entire screen. Perhaps autocompletion triggered some expensive checks. Or perhaps there's just too many badly-written functions firing, and it added up to a noticeable delay.

For me, the three most common cases of annoying little delays were autocompletion (in Elisp, and Common Lisp via SLIME), font-lock and org mode folding. The latter two were an issue when working with large org mode files.

Native compilation improved Elisp performance across the board, and all but eliminated these issues for me. It won't help you if you put a badly written function in a frequently firing hook, but it does push some of the more expensive computations below the threshold of visibility, and makes it less likely that a lot of functions in a hook will add up to a noticeable delay.

Re: Bringing GNU Emacs to Native Code (2020)

#126

Slime didn't work for me in this version of Emacs. (Slime is the Common Lisp IDE for Emacs). I don't remember the details but I think Slime was getting confused about .el vs .elc files and assuming there was no third option, but now there is.

Interesting, I've been using Slime with nativecomp for a long time.

Wow. Guess I need to try again.

Re: Bringing GNU Emacs to Native Code (2020)

#127
post #109

Earlier quoted context omitted.

Forgive my ignorance, but why would doing all of the application work on a single thread make more sense 35 years ago?

The first consumer processors with multiple cores came out around 2005. Before there were multiple cores in consumer machines, there was no reason to implement concurrency in a way that would scale to multiple cores.

Not to mention, back when the Emacs we know today was created, there weren't many GUI platforms available in the first place. First public release of GNU Emacs - the one with Emacs Lisp - was in 1985, so the Emacs we know is ~3 years older than X11. Emacs added GUI support in 1986[0] - before X11 was a thing (though X itself existed since 1984).

Emacs started as a terminal app, the GUI was added as an afterthought, by pretending it's a TTY. The concept of a "UI thread" wasn't on Stallman's mind back then. It continued to evolve from there; fast forward 35 years, and now we're living with a GUI program that still thinks it's writing to a teletype[1].

--

[0] - https://stackoverflow.com/questions/10084842/first-gui-versi...

[1] - https://m.facebook.com/nt/screen/?params=%7B%22note_id%22%3A...

Re: Bringing GNU Emacs to Native Code (2020)

#128

Earlier quoted context omitted.

With respect, I think you're confused. But even if I'm right, that's OK, software is complicated, and it took me a while to get these things straight. Multiple installed emacs packages do not execute their code simultaneously unless they are using something like run-with-timer to schedule tasks on the event loop. Can you give me an example of an emacs package that causes custom elisp to be "running in your buffer" co…

> Multiple installed emacs packages do not execute their code simultaneously unless they are using something like run-with-timer to schedule tasks on the event loop. It's true that few things run in the background constantly. You can check for that easily, with M-x list-timers. On my work laptop, my most feature-packed Emacs instance, I currently have three timers active (and 11 waiting for a trigger). Those three ar…

Ah, thanks for explaining that so clearly and thoroughly. You're right that I was forgetting hooks. (And I learned something else from what you wrote -- that often a library will have it's triggered function merely enqueue a task. Of course that makes sense but I'd forgotten that in an emacs context (whereas I might have thought of it in a backend web dev context)). Two questions/comments:

1. I had it in my head that emacs arranged for font lock to be done in a separate thread? (Also, why is it called "lock"? I just use that word cos the emacs docs and code do)

2. Isn't org mode folding/unfolding just a blocking call that happens when you ask it to?

Re: Bringing GNU Emacs to Native Code (2020)

#129

Earlier quoted context omitted.

> Multiple installed emacs packages do not execute their code simultaneously unless they are using something like run-with-timer to schedule tasks on the event loop. It's true that few things run in the background constantly. You can check for that easily, with M-x list-timers. On my work laptop, my most feature-packed Emacs instance, I currently have three timers active (and 11 waiting for a trigger). Those three ar…

Ah, thanks for explaining that so clearly and thoroughly. You're right that I was forgetting hooks. (And I learned something else from what you wrote -- that often a library will have it's triggered function merely enqueue a task. Of course that makes sense but I'd forgotten that in an emacs context (whereas I might have thought of it in a backend web dev context)). Two questions/comments: 1. I had it in my head that…

> emacs arranged for font lock to be done in a separate thread

I'm not sure, but I don't think so. There's this thing called `jit-lock-mode' (check out the docstring of the function named jit-lock-mode for details) that makes Emacs fontify only visible parts of the buffer when triggered by redisplay code (in C core), + some extra fontification of the invisible parts on idle timer. But I don't believe it actually happens on a separate thread, given that redisplay can run arbitrary user code, e.g. through 'display property attached to a piece of text in a visible buffer.

> Also, why is it called "lock"? I just use that word cos the emacs docs and code do

So do I. I did a little googling, but couldn't find any definitive answer. Most likely explanation[0] seems to be that "lock" here means the fontification spec is attached to the text and updated automatically, vs. being refreshed globally on user request.

> Isn't org mode folding/unfolding just a blocking call that happens when you ask it to?

It is, but it's also something I do very frequently in quick succession. I'll usually press S-Tab in quick succession to perform global visibility cycling, because I often want to take a quick look at the outline of my file, and then get back to editing where I was. If it takes more than a fraction of a second, it's distracting for that use case.

--

[0] - https://old.reddit.com/r/emacs/comments/b3jsfc/what_does_loc...

Post reply on HN