# Is there plans for improving the performance of the generated code from the racket compiler?

**URL:** <https://racket.discourse.group/t/is-there-plans-for-improving-the-performance-of-the-generated-code-from-the-racket-compiler/2593>\
**Category:** Internals\
**Tags:** question\
**Created:** [December 11, 2023, 11:50pm UTC](https://racket.discourse.group/t/is-there-plans-for-improving-the-performance-of-the-generated-code-from-the-racket-compiler/2593 "2023-12-11T23:50:46Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jobhdez](https://avatars.discourse-cdn.com/v4/letter/j/b19c9b/32.png) [@Jobhdez](https://racket.discourse.group/u/Jobhdez)\
**Post date:** [December 11, 2023, 11:50pm UTC](https://racket.discourse.group/t/is-there-plans-for-improving-the-performance-of-the-generated-code-from-the-racket-compiler/2593/1 "2023-12-11T23:50:46Z")

</div>

Hello,

Hope all is well.

I am just curious if the racket core team has plans to making the generated code from the racket compiler faster. In a recent benchmark [Racket&nbsp;vs&nbsp;Lisp SBCL - Which programs are fastest?](https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/racket.html), racket is faster than lisp (sbcl) three times.

I am aware that benchmarks do not mean anything but im just curious if racket will be faster in the future.

thanks.

---

<div class="post-metadata">

**Author:** ![jbclements](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jbclements/32/11_2.png) [@jbclements](https://racket.discourse.group/u/jbclements)\
**Post date:** [December 12, 2023, 1:03am UTC](https://racket.discourse.group/t/is-there-plans-for-improving-the-performance-of-the-generated-code-from-the-racket-compiler/2593/2 "2023-12-12T01:03:16Z")

</div>

I just took a quick look at the SBCL benchmarks, it looks like SBCL supports compiler directives that disable safety checks. While I think it would in principle be possible to add unsafe uses of the ffi library to simulate something like this, I'm not sure this kind of race-to-the-bottom is necessarily a good use of anyone's time. Just my two cents, of course.

---

<div class="post-metadata">

**Author:** ![samth](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/samth/32/3_2.png) [@samth](https://racket.discourse.group/u/samth)\
**Post date:** [December 12, 2023, 3:15am UTC](https://racket.discourse.group/t/is-there-plans-for-improving-the-performance-of-the-generated-code-from-the-racket-compiler/2593/3 "2023-12-12T03:15:50Z")

</div>

Racket also supports compiler directives to disable safety checks, although they may disable fewer checks than SBCL.

---

<div class="post-metadata">

**Author:** ![louis771](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/louis771/32/1796_2.png) [@louis771](https://racket.discourse.group/u/louis771)\
**Post date:** [May 18, 2024, 11:23am UTC](https://racket.discourse.group/t/is-there-plans-for-improving-the-performance-of-the-generated-code-from-the-racket-compiler/2593/4 "2024-05-18T11:23:21Z")

</div>

Since the link in the original post no longer works, here are the two implementations (Racket and SBCL):

> **[Racket performance measurements (Benchmarks Game)](https://benchmarksgame-team.pages.debian.net/benchmarksgame/measurements/racket.html)**
>
> Performance measurements for all the Racket toy benchmark programs.

> **[Lisp SBCL performance measurements (Benchmarks Game)](https://benchmarksgame-team.pages.debian.net/benchmarksgame/measurements/sbcl.html)**
>
> Performance measurements for all the Lisp SBCL toy benchmark programs.

SBCL is 3 to 10 times faster than Racket with a few exceptions. Also memory usage in Racket is much higher. However it is unclear what could be optimized by proper compiler settings.

That may not play a big role for recreational or academic purposes, but - IMHO - hinders adoption of Racket in professional situations severly.

In forums I often read "but it's faster than Python!", which might be (hopefully) the case. But taking the slowest mainstream language on the planet as a comparison should not be considered meaningful.

Racket is the _perfect_ version of any Lisps I know out there with regards to tooling, documentation & learning material, stdlib, ecosystem. I find that performance improvements should be a critical goal if wider adoption is an intended target.

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [May 18, 2024, 5:52pm UTC](https://racket.discourse.group/t/is-there-plans-for-improving-the-performance-of-the-generated-code-from-the-racket-compiler/2593/5 "2024-05-18T17:52:02Z")

</div>

@louis771

Benchmarks are difficult. They only make sense, when apples are compared to apples.  
Some of the language benchmarks are not exactly equivalent.

So instead of a general "be faster" comment, pick a single benchmark that measures a specific feature. Maybe the benchmark code can be improved - or maybe we find something that can be improved in Racket itself.

PS: I do not agree with the premise that speed alone "hinders adoption of Racket in professional situations". Look at Python. They solve the problem by writing speed  
critical code in C. A lot of "Python" libraries are just C libraries in disguise.

---

<div class="post-metadata">

**Author:** ![sschwarzer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sschwarzer/32/1940_2.png) [@sschwarzer](https://racket.discourse.group/u/sschwarzer)\
**Post date:** [May 19, 2024, 2:42am UTC](https://racket.discourse.group/t/is-there-plans-for-improving-the-performance-of-the-generated-code-from-the-racket-compiler/2593/6 "2024-05-19T02:42:31Z")

</div>

> [@soegaard](#):
>
> Some of the language benchmarks are not exactly equivalent.

I agree. I haven't checked the benchmarks apart from some quick looks, but in the past I noticed benchmarks in the Benchmarks Game sometimes use very unidiomatic code. I believe the benchmark results often depend more on how much time someone invested in the optimization than on what language implementations are faster for ideomatic code or can be tuned relatively easily. I suspect the Benchmark Games benchmarks are only mentioned so often because other benchmarks are harder to find (availability bias).

> [@soegaard](#):
>
> PS: I do not agree with the premise that speed alone "hinders adoption of Racket in professional situations". Look at Python. They solve the problem by writing speed  
> critical code in C. A lot of "Python" libraries are just C libraries in disguise.

On the other hand, the Python community is so much larger that these bindings and other extensions actually get written. So in practice the "out of the box" speed will matter for Racket much more than for Python.

Apart from that, sometimes it's very difficult to find a subset of code to be written in low-level languages that will make the code overall significantly faster. If that's the case, "native" language implementation speed will matter more than speed including low-level code. That applies to both Racket and Python, but Python is more widespread to begin with, so Racket needs to provide more to be similarly attractive.

---

<div class="post-metadata">

**Author:** ![gus-massa](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/gus-massa/32/507_2.png) [@gus-massa](https://racket.discourse.group/u/gus-massa)\
**Post date:** [May 19, 2024, 1:16pm UTC](https://racket.discourse.group/t/is-there-plans-for-improving-the-performance-of-the-generated-code-from-the-racket-compiler/2593/7 "2024-05-19T13:16:21Z")

</div>

> [@sschwarzer](#):
>
> On the other hand, the Python community is so much larger that these bindings and other extensions actually get written.

I'm ashamed, but it took me a few years to realize that OpenCV was not written in Python.

(Does Racket has a OpenCV wrapper package? Is there a nice blog post that uses it for something nice?)

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [May 19, 2024, 2:58pm UTC](https://racket.discourse.group/t/is-there-plans-for-improving-the-performance-of-the-generated-code-from-the-racket-compiler/2593/8 "2024-05-19T14:58:53Z")

</div>

There are two older projects on Github:

[Repository search results · GitHub](https://github.com/search?q=racket%20opencv&type=repositories)

Alternatively, you could try using the Python bindings for OpenCV through Pyffi (if you are on macOS or Linux).

[pyffi - Use Python from Racket](https://soegaard.github.io/pyffi/)

---

<div class="post-metadata">

**Author:** ![samth](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/samth/32/3_2.png) [@samth](https://racket.discourse.group/u/samth)\
**Post date:** [May 20, 2024, 6:42pm UTC](https://racket.discourse.group/t/is-there-plans-for-improving-the-performance-of-the-generated-code-from-the-racket-compiler/2593/9 "2024-05-20T18:42:21Z")

</div>

In general, the better performance that you see in SBCL on those benchmarks is mostly a result of the following:

1. Better support for lightweight parallelism for CPU-intensive tasks (as compared to Racket futures).
2. Better use of vector instructions (eg AVX), which Racket mostly does not generate.
3. More ability to express extremely low-level code, as you see [here](https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/mandelbrot-sbcl-4.html).

Obviously improving all of those (especially the first one) would be nice, but they aren't mostly in the way of the kinds of applications that people usually build with Racket. Certainly Racket has performance issues that it would be good to fix, but I don't think the benchmarks game is a good guide to them.

---

<div class="post-metadata">

**Author:** ![dstorrs](https://avatars.discourse-cdn.com/v4/letter/d/898d66/32.png) [@dstorrs](https://racket.discourse.group/u/dstorrs)\
**Post date:** [May 26, 2024, 5:20pm UTC](https://racket.discourse.group/t/is-there-plans-for-improving-the-performance-of-the-generated-code-from-the-racket-compiler/2593/10 "2024-05-26T17:20:34Z")

</div>

> [@samth](#):
>
> Better support for lightweight parallelism for CPU-intensive tasks (as compared to Racket futures).

My knowledge about parallelism in specific and low-level programming in general could be painlessly engraved on my eyeball, so this is probably a dumb and/or obvious question, but I was wondering about it. Feel free to say "it's complicated, don't worry about it" or "this is how it works everywhere in all Lisps" and I'll drop it.

As I understand it, Racket's threads (A) are managed by Racket itself instead of going to the operating system's thread scheduler and (B) all run on the same CPU core. Do I have that right? If so, why?

---

<div class="post-metadata">

**Author:** ![samth](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/samth/32/3_2.png) [@samth](https://racket.discourse.group/u/samth)\
**Post date:** [May 26, 2024, 5:41pm UTC](https://racket.discourse.group/t/is-there-plans-for-improving-the-performance-of-the-generated-code-from-the-racket-compiler/2593/11 "2024-05-26T17:41:13Z")

</div>

Racket has three related constructs for managing independent tasks: threads, futures, and places. Threads work as you say. Futures are also managed by Racket but can be run on different OS threads. Places are effectively separate copies of the VM, which always run in separate OS threads.

---

<div class="post-metadata">

**Author:** ![benknoble](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/benknoble/32/16_2.png) [@benknoble](https://racket.discourse.group/u/benknoble)\
**Post date:** [May 26, 2024, 7:28pm UTC](https://racket.discourse.group/t/is-there-plans-for-improving-the-performance-of-the-generated-code-from-the-racket-compiler/2593/12 "2024-05-26T19:28:23Z")

</div>

I believe a short summary would be “threads are units of concurrency; places are units of parallelism” (and futures are murky?), but that shorthand works best with an idea of concurrency vs. parallelism. (Practically, I’m also using Sam’s description in my head.)

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [May 26, 2024, 7:50pm UTC](https://racket.discourse.group/t/is-there-plans-for-improving-the-performance-of-the-generated-code-from-the-racket-compiler/2593/13 "2024-05-26T19:50:38Z")

</div>

FWIW Jim Bender curated a bibliography on Scheme related papers on " Distributed, Parallel, and Concurrent Programming"

> **[Distributed, Parallel, and Concurrent Programming](https://web.archive.org/web/20180317194324/http://library.readscheme.org/page9.html)**
>
> Online bibliography of Scheme research

Implicit in Sam's listing is that threads are cheaper than futures, and futures are cheaper than places.

---

<div class="post-metadata">

**Author:** ![dstorrs](https://avatars.discourse-cdn.com/v4/letter/d/898d66/32.png) [@dstorrs](https://racket.discourse.group/u/dstorrs)\
**Post date:** [May 27, 2024, 12:44am UTC](https://racket.discourse.group/t/is-there-plans-for-improving-the-performance-of-the-generated-code-from-the-racket-compiler/2593/14 "2024-05-27T00:44:30Z")

</div>

I thought that places ran in a separate process, not a separate thread. Is that wrong?

Separately: based on what I've read about futures it feels like they basically aren't worth using because they overly restrict the operations you can use and it's hard to predict if you will invalidate the future. That's the impression that the docs give, anyway.

---

<div class="post-metadata">

**Author:** ![robby](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/robby/32/7_2.png) [@robby](https://racket.discourse.group/u/robby)\
**Post date:** [May 27, 2024, 1:43am UTC](https://racket.discourse.group/t/is-there-plans-for-improving-the-performance-of-the-generated-code-from-the-racket-compiler/2593/15 "2024-05-27T01:43:12Z")

</div>

There is a mode where you can run places will run in separate processes, but in most environments, they are in the same OS process, I believe.

---

<div class="post-metadata">

**Author:** ![samth](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/samth/32/3_2.png) [@samth](https://racket.discourse.group/u/samth)\
**Post date:** [May 28, 2024, 4:06pm UTC](https://racket.discourse.group/t/is-there-plans-for-improving-the-performance-of-the-generated-code-from-the-racket-compiler/2593/16 "2024-05-28T16:06:41Z")

</div>

Futures are certainly somewhat limited but I wouldn't say they're not worth using; it just requires somewhat more care to use them well.

@benknoble The way I would put it is that threads guarantee concurrency and provide no parallelism, futures provide opportunistic concurrency and parallelism but you cannot rely on either, and places guarantee both.

---

<div class="post-metadata">

**Author:** ![LiberalArtist](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/liberalartist/32/151_2.png) [@LiberalArtist](https://racket.discourse.group/u/LiberalArtist)\
**Post date:** [May 28, 2024, 7:59pm UTC](https://racket.discourse.group/t/is-there-plans-for-improving-the-performance-of-the-generated-code-from-the-racket-compiler/2593/17 "2024-05-28T19:59:42Z")

</div>

> [@dstorrs](#):
>
> based on what I've read about futures it feels like they basically aren't worth using because they overly restrict the operations you can use and it's hard to predict if you will invalidate the future.

> [@samth](#):
>
> Futures are certainly somewhat limited but I wouldn't say they're not worth using; it just requires somewhat more care to use them well.

I found Matthew's talk [Incremental Parallelization of Dynamic Languages | Air Mozilla | Mozilla, in Video](https://web.archive.org/web/20161014095622/https://air.mozilla.org/incremental-parallelization-of-dynamic-languages/) useful context for futures. Unfortunately, it looks like Mozilla Air moved to a new CMS and didn't import old videos, and the Internet Archive page I linked to doesn't seem to have archived the actual video: maybe someone can find another source?

With respect to discussions about the limitations of futures one might read in various places, a big change came with the move to Racket CS, and I think we are (certainly I am) still gaining experience with what is now possible.

Racket BC was originally single-threaded, and most operations ended up blocking futures from running in parallel. (This was explained well in the Mozilla talk. I particularly remember a picture of a bike covered with an extreme number of locks.) What worked in Racket BC was primarily carefully written numeric code.

In Racket CS, _most_ primitives are now future-safe (by virtue of Chez Scheme's support for OS-level threads), basically the opposite of the Racket BC situation! I found the diff from [guide: update discussion on futures for Racket CS · racket/racket@4fcecee · GitHub](https://github.com/racket/racket/commit/4fcecee53c61e44687696a1116137c3a7c12f368) an interesting view into what changed.

That said, there is certainly also room for improvement, e.g. (as @samth wrote [here](https://racket.discourse.group/t/what-is-the-racket-roadmap/2204/28)) finding a way to make IO operations "synchronized" rather than "blocking".

> [@robby](#):
>
> There is a mode where you can run places will run in separate processes, but in most environments, they are in the same OS process, I believe.

Are you thinking of the `--processes` mode for e.g. `raco setup`? IIUC, places always use OS threads in the same OS process when they are able to run in parallel, and that mode exists to enable process parallelism when parallel places aren't supported (as was the case on non-x86{,\_64} with Racket BC), but has to be implemented explicitly in `raco setup`. I don't think ordinary places ever run in separate OS processes.

(I say "normal places" because [`loci`](https://docs.racket-lang.org/loci/index.html) by Paulo Matos and [`racket/place/distributed`](https://docs.racket-lang.org/distributed-places/index.html) exist, and [`prop:place-location`](https://docs.racket-lang.org/reference/places.html#%28def._%28%28lib._racket%2Fplace..rkt%29._prop~3aplace-location%29%29) provides some extensibility.)

(Tangentially, I wonder if the bottleneck from the OS page table described in [docs: describe some limits of place scaling · racket/racket@b223ce4 · GitHub](https://github.com/racket/racket/commit/b223ce471ec38c61f37e0a458d54fabf525324cb) and [this thread](https://groups.google.com/g/racket-users/c/oE72JfIKDO4/m/IYggL09WBAAJ) also applies with Racket CS. I don't have any machines with more than 16 cores to check.)

> [@louis771](#):
>
> Since the link in the original post no longer works, here are the two implementations (Racket and SBCL):
> 
> [Racket performance measurements (Benchmarks Game)](https://benchmarksgame-team.pages.debian.net/benchmarksgame/measurements/racket.html)

> [@samth](#):
>
> Certainly Racket has performance issues that it would be good to fix, but I don't think the benchmarks game is a good guide to them.

I agree with @samth on this, but, if someone wants to spend time making the benchmarks look faster, adding [`(#%declare #:unsafe)`](https://docs.racket-lang.org/reference/module.html#%28idx._%28gentag._104._%28lib._scribblings%2Freference%2Freference..scrbl%29%29%29) would probably give at least some benefit without requiring deep thought. (Unlike using `(#%declare #:unsafe)` in real life!)
