5 ms·
Lisp solves the performance hit of closures with macros. However, given what macros look like in C, I hope it never amounts to that!
by djaouen 9mo ago
Lisp solves the performance hit of closures with macros. However, given what macros look like in C, I hope it never amounts to that!
- skavi 9mo agoThere’s no necessary performance hit for closures. The performance cost here is caused by these closures needing to conform to a function pointer looking interface in order to be generally useful in C.
- djaouen 9mo agoIirc, in Lisp, closures are heap-allocated, unless they are created at compile-time with macros. Therefore, there is the added overhead of malloc and free calls with each closure created. Am I wrong here?
- BoingBoomTschak 9mo agoYes, in that normal closures being stack or heap allocated is an implementation detail; at least in CL. SBCL can stack allocate some closures if DYNAMIC-EXTENT is used: https://www.sbcl.org/manual/#Stack-allocation-1 https://www.sbcl.org/manual/#Stack-allocation-1
- deleted 9mo ago[deleted]
- pfdietz 9mo agoOr I believe if it can determine the closure has dynamic extent, for example if it's passed to a standard function for which it knows the closure will not escape.
- BoingBoomTschak 9mo agoIndeed, it's newish (from this summer https://github.com/sbcl/sbcl/releases/tag/sbcl-2.5.6 https://github.com/sbcl/sbcl/releases/tag/sbcl-2.5.6) and mainly thanks to C. Zhang's work. https://github.com/sbcl/sbcl/commit/021414445224e692ebb9c48c0505b0c1ffc10669 https://github.com/sbcl/sbcl/commit/021414445224e692ebb9c48c... https://github.com/sbcl/sbcl/commit/2c56c5901df1a5ea98ae19e966ec9315be3ebfb9 https://github.com/sbcl/sbcl/commit/2c56c5901df1a5ea98ae19e9...
- pfdietz 9mo agoLisp implementations typically don't use malloc and (especially) free. There is GC overhead.
- kazinator 9mo agoDefinitely. Lisp is a family of languages that has now existed for almost 70 years. There simply isn't one way that closures work in "Lisp". Some implementations of languages in the lisp family have compilers that have sophisticated ways of handling closures. They carefully classify what is or is not captured by closure (and what is shared with other closures and what is mutably shared), and try to guess whether a closure can escape from the environment where it's created. Different code generation strategies, and strategies for representing the environment, apply to different situations.