[HN Gopher] Optimizing Guile Scheme
___________________________________________________________________
Optimizing Guile Scheme
Author : avvvv
Score : 120 points
Date : 2024-09-20 11:28 UTC (5 days ago)
(HTM) web link (dthompson.us)
(TXT) w3m dump (dthompson.us)
| orliesaurus wrote:
| As soon as I saw the title, I thought of the streetfighter
| character, but this was actually an interesting read on a
| programming language, I had never heard of before
| abound wrote:
| A prominent use of Guile is as the configuration language for
| Guix, GNU's version of Nix
| pxc wrote:
| It's the official GNU extension language, so it's fairly
| widely used in the GNU world I think.
|
| It's also the language of the init system/service manager on
| GuixSD (the full OS distribution based on Guix), GNU Shepherd
| (a.k.a. dmd), and IIRC their initrd runs a Guile program
| instead of a shell script.
| bitwize wrote:
| The slogan I've proposed for the language is "Guile goes with
| everything." Because Guile was designed from the outset to run
| embedded or standalone, and to transpile other extension
| languages to Scheme or a Scheme-compatible representation, I
| think that fitting. See: https://knowyourmeme.com/memes/guiles-
| theme-goes-with-everyt...
| davexunit wrote:
| I think the Guile community of yore would have no idea what
| Street Fighter was but now we should embrace it as long as
| Capcom doesn't get mad.
| bitwize wrote:
| The other Scheme environment I use regularly is Gambit. So,
| reppin both Marvel and Capcom.
| fwip wrote:
| Should it be "Guile Scheme goes with everything" for the
| rhyme?
| pjmlp wrote:
| Great overview on how to approach improving code performance,
| without going down the usual route of rewriting into something
| else.
| throwaway17_17 wrote:
| Solid blog overall and I think it is pitched at the right level
| of granularity for the topic. However, if I were offering
| criticism, the place I think more detail would be super
| interesting is the 'Please Inline' section. In particular, I
| would really be interested in a slightly more detailed
| description of the optimizer's algorithm for inlining. I think
| the "define_inlinable" macro is a great example of macro usage,
| but it is clearly a way to circumvent the inliner's apparent
| short comings. I would like to be able to understand what
| heuristic the optimizer is using to see if there is a sensible
| default function construction style/idiom that is more appealing
| to the optimizer for inlining. However, I am reminded of the
| inlining discussion in Chandler Carruth's talk (Understanding
| Compiler Optimization) from a few years ago where he discusses
| how obscure and seemingly arbitrary, in general, inlining
| heuristics and their optimization passes are in practice. [1]
|
| 1 - https://youtu.be/FnGCDLhaxKU?si=J3MhvJ-BmX5SG2N6&t=1550
| davexunit wrote:
| A walkthrough of Guile's optimization passes and the inlining
| heuristics would be great. I've been meaning to do a "part two"
| here but you know how these things go.
| atemerev wrote:
| These sorts of optimizations can and should be handled by a
| (sufficiently smart (tm)) compiler.
|
| Common Lisp/SBCL is usually sufficiently smart. I know not
| everyone likes Common Lisp, but at least I would have tested it
| with something more performant that Guile, like Chicken Scheme
| (my favorite!), Chez Scheme, etc.
|
| I like Guile and its purpose as a universal scripting language.
| However, its performance issues are well known. Even compared to
| other scripting-first languages (Lua, Perl, Python etc).
| throwaway17_17 wrote:
| I think that is why this blog is particularly interesting to
| me. As one of the other comments to this posting said, it is
| nice to see an analysis/detailed description of working to
| optimize code where the first step is not to rewrite in a
| language with a presumed better performance baseline. Also, I
| think there is also some props to be given for continuing to
| work within Guile's somewhat spartan tooling to do the
| optimization work, instead of switching to a language that may
| have more/better tooling for the task.
|
| Not to take away from the general comparisons between various
| Lisp flavors and between various scripting languages (an
| activity I engage in quite often), but your lead off line is
| more prescriptive than I find advisable. I don't think a
| blanket statement that optimizations of runtime behavior of
| code "should" only be done via a compiler. Some devs enjoy the
| work, others have varied reasons for doing performance
| sensitive work in a given language/environment. But at the end
| of day, doing optimization is a valid usage of developer effort
| and time if that developer judges it so.
| eru wrote:
| Isn't Racket the 'default' Scheme? (Even though it's no longer
| called Scheme.)
| medo-bear wrote:
| No
| umanwizard wrote:
| Extremely easy interop with native code is the main selling
| point of guile IMO. You just link in guile as a library and
| can have C code call scheme code and vice versa. Makes it
| great for any native program that needs an embedded scripting
| language (much like Lua). Does Racket support that use-case?
| mepian wrote:
| At this point it's a separate language from Scheme. I think
| Chez Scheme tends to be the "default" recommendation.
| tmtvl wrote:
| I don't think there's a real 'default' Scheme, like Chez is
| probably the implementation which generates the fastest code,
| but if I'm not mistaken it only implements the R6RS spec,
| Guile is quite performant and supports both R6RS and R7RS
| Small, Chicken has a bunch of libraries (the 'eggs'), but I
| think it's R5RS (I may be wrong), and of course GNU/MIT
| Scheme is what you want to follow along with MIT publications
| working in Scheme (like Structure and Interpretation of
| Computer Programs, Structure and Interpretation of Classical
| Mechanics, and The Art of the Propagator). There's also
| Gauche, which I believe is the most conformant implementation
| to the various Colour Dockets for R7RS Large (Gerbil may also
| be fully conformant).
| wbl wrote:
| Racket is now built around Chez.
| gus_massa wrote:
| You can download a package to use R7RS Small in Racket.
| https://github.com/lexi-lambda/racket-r7rs
| davexunit wrote:
| Guile has come a long way in the past decade or so! I think
| your info is quite out of date. Guile's compiler performs a
| number of state of the art optimizations. It compiles to
| bytecode so native code compilers like Chez win the race,
| naturally. The JIT is pretty good, though! Native compilation
| is on the roadmap for Guile, but maybe somewhat surprisingly
| we're getting AOT compilation to WebAssembly first.
| https://spritely.institute/hoot/
| armitron wrote:
| It's still much much slower than SBCL which is not surprising
| given the time & effort that went into the latter. User-
| guided optimizations (type declarations, stack allocation,
| intrinsics, machine code generation) in SBCL are also more
| flexible and better integrated.
| davexunit wrote:
| Yup, SBCL is quite amazing!
| tmtvl wrote:
| I switched from Guile to SBCL because I really like having
| things such as (declare (inline my-function)) and (declare
| (type Double-Float x y z)). Now if only it had case-lambda,
| named let, and a better deftype which can specify members of
| classes and/or structs.
| whartung wrote:
| Part of the problem is that raw Scheme is spectacularly
| underspecified.
|
| It also doesn't help that Schemes like Guile are also
| interactive. The domain of an interactive language and a
| "compiled" language are quite different.
|
| Given the entirety of the program made available to the
| compiler all at once, there are high level derivations that can
| happen notably through flow analysis to let the compiler make
| better decisions. But do that in an interactive environment
| when the rug can be pulled out of any of the assumption the
| compiler made, and things get messy quite quickly.
|
| One interesting tidbit for Java is that the developers of the
| compiler advocate "idiomatic" Java. Simply, write Java like
| Java, and don't try to trick the compiler. Let the compiler
| developers trick the compiler.
|
| That's evident here in this article when they wrote the
| function that tests the types of the parameters. Raw Scheme,
| naturally, doesn't allow you to specify parameter types, not
| the way you can in Common Lisp, for example. And, either Guile
| does not have an specific extension to support this, or simply
| the compiler looks for this type checking pattern at the top of
| a function to make optimization determinations. On the one
| hand, it could be more succinct with a specialized facility,
| but on the other, this is "just Scheme".
|
| So, in effect by checking for the type of the variable, they're
| implicitly declaring the type of the variable for the
| "sufficiently smart" compiler to make better decisions.
|
| The counter example is the "define-inline" construct, and thus
| not standard Scheme (though readily replaced by a "no-op" macro
| if one was interested in porting the code).
| munificent wrote:
| I have such mixed feelings about dynamically typed languages.
| I've designed a whole pile of hobby programming languages, and
| dynamically typed languages are at least an order of magnitude
| simpler to design and for users to learn and start using.
|
| At the same time, they inevitably seem to lead to user stories
| like this where a user really does know exactly what types
| they're working with and wants the language to know that too (for
| performance or correctness), and they end up jumping through all
| sorts of insane hoops to get the optimizer to do exactly what
| they want.
| sctb wrote:
| I like dynamic languages too. But I don't like the idea of
| "optimization", and I would be super interested in a dynamic
| language that didn't attempt to divorce performance from
| correctness. The worst part about jumping through insane hoops
| to enchant the optimizer is that it can all go wrong with the
| tiniest change--a flag here, a different usage pattern there, a
| new version, etc., and suddenly your program doesn't do what
| you need it to, as though an operation taking 1000x longer is
| just a matter of degree.
| munificent wrote:
| I agree completely.
|
| At the same time, no one wants their code to run 100x slower
| than it would in any typical statically typed language.
| Unoptimized dynamic languages are _sloooooow_.
| zem wrote:
| stanza (https://lbstanza.org/) is a very interesting experiment
| in designing for gradual types rather than retrofitting them
| onto a dynamic language
| davexunit wrote:
| I'm happy with dynamic languages for almost everything I do and
| generally do not want to sacrifice flexibility, which is the
| price to pay for a static type system. However, certain parts
| of a program become more crystalline over time, whether for
| performance or correctness reasons, and being able to express
| those parts using a static type system makes a lot of sense.
| PreScheme [0] is an example of a statically typed Scheme that
| composes with the host Scheme. I'd like to see more work in
| this direction as Scheme already works well as a multi-paradigm
| language.
|
| [0] https://prescheme.org/
| cardanome wrote:
| I think Common Lisp got it exactly right. Strongly typed
| dynamic language where you can optionally specify types for the
| extra performance/correctness if need be (especially with
| SBCL).
|
| Honestly, I think weak typing is more of an issue than dynamic
| typing and people cry for static types when they suffer mostly
| from the former.
|
| Dynamic typing is great because it allows you to have extremely
| complex types for basically free. It allows for insane
| expressiveness. It also makes prototyping much easier and does
| not force you into over-specifying in you types early on. In
| dynamic language most of your types are the most general type
| that would work by default while static types forces you to use
| very specific types (especially when lacking structural
| typing.)
|
| If you want to allow just half the expressiveness of dynamic
| languages in your static language you will quickly find huge
| complexity with dependent types, long compile time, cryptic
| error messages and whatnot.
|
| Generally, I think gradual typing is rising in popularity for
| good reason. It allows for quick prototyping but also to drill
| down on your types when you want to. Best of both worlds.
| samatman wrote:
| If you want to read just an enormous amount of well-written
| bloggage about optimizing Guile Scheme, this is the spot:
| https://wingolog.org
|
| Andy Wingo is the maintainer and I get a kick out of everything
| he posts.
| davexunit wrote:
| Andy's blog is on another level. He's also leading the Hoot
| project to compile Guile to WebAssembly and I work with him on
| that and try to absorb whatever compiler knowledge I can while
| doing so.
| exitb wrote:
| You probably shouldn't do those things. The point of a high level
| language is to not have to think about such details. If you can't
| get the performance you need, you should use a different tool,
| instead of trying to circumvent implicit limitations.
| anthk wrote:
| I prefer Common Lisp with SBCL and Lem, but this is good too.
|
| On SICP, Guile badly needs a module for the picture language from
| the book (and srfi-203 + srfi-216).
___________________________________________________________________
(page generated 2024-09-25 23:00 UTC)