[Top][All Lists]

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

Re: Why is Elisp slow?

From: Ergus
Subject: Re: Why is Elisp slow?
Date: Fri, 3 May 2019 11:58:49 +0200
User-agent: NeoMutt/20180716

On Fri, May 03, 2019 at 10:00:45AM +0300, Eli Zaretskii wrote:
Date: Fri, 3 May 2019 02:44:16 +0200
From: Ergus <address@hidden>
Cc: address@hidden

Having Guile as a dependency will grow emacs size significantly
and using it as an external dependency (not usually the emacs way...)
will require to port Guile to more systems (AFAIK).

Which systems we care about are not already supported by Guile?

Actually in windows I have a friend who tried it and the experience was
not convincing for him. And the native code compiler was in fact
tremendously slow in a power9 machine. It felt like a hack in both
cases more than a real native application.

The alternative JIT may be based in libJIT which is not very active
either... and has serious issues/limitations that has not been solved in

There's a branch in the Emacs repository that uses libJIT.  It has
problems with some Emacs configurations, which need to be solved in
libJIT.  Alas, those problems, reported months ago to the libJIT
developers, are still not fixed.

More importantly, the libJIT build failed to show any significant
speed-up wrt byte code, so it sounds like maybe the whole idea was
either wrong or its design couldn't possibly provide any gains.  Or
maybe we just measured the speed-up in wrong scenarios.

This is not surprising. My work is 80% performance measurement and
benchmarking and the real improvements with JIT compilation (in my
experience) and specially with libJIT is not as good as many people
expect in most of the common scenarios. That's because the generated
code is usually very generic (so it does not take advantage of
architecture specific features), and strategies like vectorization and
branch prediction are very difficult to hint (most of the times
impossible). So the only real difference with a bytecode interpreter is
the bytecode parsing part, but not too much more.

There is also the typical array of struct vs struct of arrays problem, type
aligns and the optimal memory management what are also very dark to
advice for a JIT compiler. The use of dark types and pointers to
functions produces huge overheads and they are extensively used in JIT
compilers internally generated code, the impossibility to do proper
inlinings, and of course the fact that coming from a higher level
language like Lisp we need more dynamic/runtime functionalities like
garbage collector and generic function types. Plus the hashtable search
costs and the extensively used list searches in Lisp instead of vectors
or similar cheaper containers and callbacks in the user code.

That's why I support the idea of the Lisp->C compiler more than the JIT
at least to use it for the emacs core Lisp functions because gcc is very
optimized and migrate the bottleneck back to C code as much as
possible. (many of the very used in simple.el for example that are
called very frequently)

That's the strategy that made python become so successfully (plus the
language simplicity). The existence of Cython, Numba + Pure C/Fortran
core libraries like numpy and a simple C API to extend it. So when a
user implements anything in 100% python; if it has performance issues
she only needs to change the python lists with numpy arrays and numpy
functions and that's it, the difference will be observed
immediately. But if a specific function still represents a problem
she can implement it easily in C or use a C library directly with
CTypes, Pybind11 or boost, that uses dlopen instead of create processes
and parse outputs and writes in numpy arrays/types directly.

So in spite of that python's virtual machine is very slow to load, the
rest of the execution is not necessarily slow and can be improved as
much as the developer desires. Also as there are more users the bytecode
part (interpreter and generator) is improved and optimized constantly.

reply via email to

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