7 ms·
> Lisp has extremely powerful code generation, but makes serious performance compromises This is a serious exaggeration. Common Lisp has extremely good compil
by elgatonegro 6y ago
> Lisp has extremely powerful code generation, but makes serious performance compromises
This is a serious exaggeration.
Common Lisp has extremely good compilers that can meet C performance.
There are plenty of Scheme implementations (I use Chez) with very good performance characteristics too.
- makuto 6y agoI do wish the C compiler was as fast as e.g. SBCL's compiler in terms of compile time, because multiple rounds of dependent macro compilation eats up a lot of time. I think Lisps tend to optimize for throughput, but games have very strict latency requirements. Garbage collection pauses could cause frame pacing issues (not that C solves that completely, but it is at least not a built in disadvantage of idiomatic use of the language)
- moonchild 6y agoNewer concurrent java GCs (shenandoah, zgc) provide consistent ≤1ms pause times independent of heap size. That's a reasonable latency for most soft real-time tasks.
- AlchemistCamp 6y agoSome older VMs like Erlang's also do very well in avoiding GC pauses. In Erlang's, the key is that garbage collection is per process. (Note that Erlang processes are analogous to Golang green threads, not OS prcessses.)
- dugmartin 6y agoAnd in the BEAM the garbage collector is only invoked when the heap and stack meet which means for most short-lived processes it never runs: https://erlang.org/doc/apps/erts/GarbageCollection.html#overview https://erlang.org/doc/apps/erts/GarbageCollection.html#over... (btw, I'm enjoying the Reactor podcast, keep it up)
- AlchemistCamp 6y ago> (btw, I'm enjoying the Reactor podcast, keep it up) Thank you! Since we don't get many comments on reactor.am, it's hard to tell if it's useful for others to share our masterminds.
- patrec 6y agoWriting a low latency garbage collector (with decent throughput) is a non-trivial engineering problem and requires both high calibre engineers with specialized skills and a lot of funding. I fear the time lisp community has had either are long gone. How much did the development of Azul's C4 or Oracle's Shenandoah cost in terms of money, talent and time and how much has this work lowered the barrier for less well resourced languages? I don't get the impression that the answer to this question is: "enough that we will soon see low-latency, high-throughput garbage collectors becoming the norm".
- bitwize 6y ago> Common Lisp has extremely good compilers that can meet C performance. Provided memory is no object. In general it takes five times as much memory for a GC'd program to be as performant as one with explicit memory management. See: https://www.cics.umass.edu/~emery/pubs/gcvsmalloc.pdf https://www.cics.umass.edu/~emery/pubs/gcvsmalloc.pdf There's a reason why the most interesting work these days is being done in and on languages like Rust, which has no GC but still saves you 90% of the work and close to 100% of the pain of bugs that are inherent to explicit memory management.
- moonchild 6y agoAt 3x memory you still get comparable performance, and memory is fairly cheap. In particular, memory sizes continue to scale, unlike CPU speeds, making GC an increasingly favourable proposition.
- imtringued 6y agoThe end result is games that use 8GB of RAM like modded Minecraft. I was perfectly happy with 8GB of RAM for the entire system but no, that one game was so inefficient that I had to upgrade my entire system. I will keep saying this over and over again. It's only cheap if you don't waste it. Once you are willing to waste it no amount of RAM will be good enough.
- _ph_ 6y ago> In general it takes five times as much memory for a GC'd program to be as performant as one with explicit memory management. In this blanket form, the statement is just wrong. Yes, with GC you need to have a larger heap space, as unreferenced objects will remain on the heap until collected and you want to have enough heap space so collections are infrequent enough, that a lot of objects can be collected (especially with generational GC, you want low survivor rates in the youngest generation). However, how much space you want to reserve for that depends on many factors. Usually the extra space is proportional to the allocation and deallocation rates, not the total heap size. If you have lots of data on the heap which is long-living, this doesn't count to the extra space. Which leads to the allocation behavior of your program in general. If you want best performance, your program shouldn't blindly create garbage, but only, where it is needed. A lot of data can be stack allocated, so not counting towards the GC. And of course, you can have some amount of memory manually managed (depending on language), for bulk data. Be it entirely allocated outside the GCed heap or by keeping references alive to memory that manually gets reused. In all of these cases, this doesn't really count towards the extra space calculation. The programming language used plays a huge role in this and the paper you quoted uses Java, which is a quite allocation-happy language, so the heap pressure is higher and you need more extra space to be performant.
- arc-in-space 6y agoRare to see Chez brought up, I've been increasingly integrating it into my own work recently. Its performance¹ and maturity of the runtime keep surprising me. ¹ Frequently on par or even better than LuaJIT, though it can take some work to get it there.
- CyberDildonics 6y agoThe power of luaJIT is that isn't doesn't take much work to get there. If you do normal things it ends up being very fast by default.
- arc-in-space 6y agoYeah, no, I agree. But my experience with it has also been that as soon as you start writing anything except simple code, its performance starts to suffer, while Chez handles complex abstractions more gracefully. So I suppose comparing them directly might be a bit unfair both ways.
- CyberDildonics 6y agoWhat kind of things end up being slow in LuaJIT?
- arc-in-space 6y agoCan't claim I remember much detail given how long I haven't worked with it. IIRC one of the issues had to do with tossing around anonymous functions inevitably causing it to give up on JITing and drop out into the interpreter
- patrec 6y agoCan you show some concrete examples? Non-idiotimatic Common Lisp compiled with SBCL can certainly come within a single digit integer factor of C, but your claim is much stronger. As for Chez, I have yet to see some code that compares favorably to even a fast scripting language, let alone a medium or high performance compiled language, and that's even if the code is littered with fixnum version of operators etc. Not what I'd call "very good performance characteristics" unless compared to bash or python.
- mtreis86 6y agoCL-PPCRE is faster than the C version
- patrec 6y agoIt used to be, and when Edi Weitz first wrote it over a decade ago it was a very elegant example of the power of having a language that makes efficient code gen at runtime both possible and easy -- a single developer was able to outperform libraries with dozen of man years of investment over a beer-bet. But I'd be extremely suprised if that were still the case or if it were even within the same order of magnitude as the fastest regexp engines. Also, despite the fact that scenarios that can leverage "jit-for-free" are both a best case scenario for lisps and not that rare in different fields (from firewall rules to stencil computations) to the best of my knowledge, even in this niche lisp plays absolutely no role in practice. To be clear, I don't think this due to any inherent shortcoming of lisp itself, indeed I suspect it's mostly due to brain-drain.
- _ph_ 6y agoI have seen tight functions compiled with SBCL matching and occasionally exceeding the speed of the C version. SBCL is a compiler which produces very good code. If you add enough type information so that SBCL can infer the types of all operations, you will get performance which compares very well to C.
- TurboHaskal 6y agoThere is no such thing as idiomatic Common Lisp.