# Futures and garbage collection

**URL:** <https://racket.discourse.group/t/futures-and-garbage-collection/1045>\
**Category:** Questions & Answers\
**Tags:** futures\
**Created:** [May 31, 2022, 9:58am UTC](https://racket.discourse.group/t/futures-and-garbage-collection/1045 "2022-05-31T09:58:54Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Laurent.O](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/laurent.o/32/18_2.png) [@Laurent.O](https://racket.discourse.group/u/Laurent.O)\
**Post date:** [May 31, 2022, 9:58am UTC](https://racket.discourse.group/t/futures-and-garbage-collection/1045/1 "2022-05-31T09:58:54Z")

</div>

Using futures (via the wonderfully simple `for/async`), I'm seeing a long sequence of numbers like these:

```scheme
cpu: 256599 real: 4585 gc: 3065

```

I'm quite happy with the speedup I already get, but it appears that the GC is taking a lot of time (I suppose the 3065 ms of GC are 'real' ms), so I'm hoping I could shave some more seconds off it.

But I don't yet see where in my code I could reduce the GC time.

The code isn't opensource yet so I can't share it unfortunately, but it uses the following operations:

- untyped flonum and fixnum operations (and _not_ using math/flonum), including `flvector-set!`, `in-flvector` and `fxquotient`
- `for/fold`, `for/async`, `define`, `unless`, `when`, `in-range`, `in-list`
- a few struct get/set, but that's not in the inner loops
- a number of `define`s for intermediate flonum values
- no closure, no named let loops, no lambda
- no generic arithmetic operations
- Racket CS 8.4.0.8

I've also read the docs on [memory management](https://docs.racket-lang.org/guide/performance.html#%28part._gc-perf%29). There are also some valuable information about [compiler hints for fixnums and flonums](https://docs.racket-lang.org/guide/performance.html#%28part._fixnums%2Bflonums%29).

Are there additional general advice about how to reduce the GC time?  
Would turning `define`s to `let`s make any difference?  
Increasing `PLT_CS_COMPILE_LIMIT`?  
Could Typed Racket help with this?

---

<div class="post-metadata">

**Author:** ![Laurent.O](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/laurent.o/32/18_2.png) [@Laurent.O](https://racket.discourse.group/u/Laurent.O)\
**Post date:** [May 31, 2022, 12:08pm UTC](https://racket.discourse.group/t/futures-and-garbage-collection/1045/2 "2022-05-31T12:08:40Z")

</div>

In the following, is there a way to give a compiler hint about the fact that `idx` is a fixnum, and that `grad` is a `flonum`, to avoid boxing?

```scheme
(for ([idx (in-list a-list-of-fixnums)]
      [grad (in-list a-list-of-flonums)])
   ...)

```

If not, would turning the lists in `fxvector` and `flvector` and using `in-fxvector` and `in-flvector` do the trick?

---

<div class="post-metadata">

**Author:** ![dominik.pantucek](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/dominik.pantucek/32/144_2.png) [@dominik.pantucek](https://racket.discourse.group/u/dominik.pantucek)\
**Post date:** [May 31, 2022, 12:45pm UTC](https://racket.discourse.group/t/futures-and-garbage-collection/1045/3 "2022-05-31T12:45:28Z")

</div>

If you can put those in flvector[1] and fxvector[2], you can use in-flvector[3] and in-fxvector[4].

[1] [https://docs.racket-lang.org/reference/flonums.html#(part.\_flvectors)](https://docs.racket-lang.org/reference/flonums.html#%28part._flvectors%29)  
[2] [https://docs.racket-lang.org/reference/fixnums.html#(part.\_fxvectors)](https://docs.racket-lang.org/reference/fixnums.html#%28part._fxvectors%29)  
[3] [https://docs.racket-lang.org/reference/flonums.html#(def.\_((lib.\_racket%2Fflonum..rkt).\_in-flvector))](https://docs.racket-lang.org/reference/flonums.html#%28def._%28%28lib._racket%2Fflonum..rkt%29._in-flvector%29%29)  
[4] [https://docs.racket-lang.org/reference/fixnums.html#(def.\_((lib.\_racket%2Ffixnum..rkt).\_in-fxvector))](https://docs.racket-lang.org/reference/fixnums.html#%28def._%28%28lib._racket%2Ffixnum..rkt%29._in-fxvector%29%29)

---

<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 31, 2022, 1:43pm UTC](https://racket.discourse.group/t/futures-and-garbage-collection/1045/4 "2022-05-31T13:43:21Z")

</div>

Fixnums don't allocate, so there's no need to worry about them taking space in the heap. For flonums, you'll really need to use more specialized data structures to avoid boxing.

---

<div class="post-metadata">

**Author:** ![Laurent.O](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/laurent.o/32/18_2.png) [@Laurent.O](https://racket.discourse.group/u/Laurent.O)\
**Post date:** [May 31, 2022, 1:48pm UTC](https://racket.discourse.group/t/futures-and-garbage-collection/1045/5 "2022-05-31T13:48:57Z")

</div>

So is there any GC-difference between `(for ([idx (in-list a-fixnum-list)]) ...)` and `(for ([idx (in-fxvector a-fxvector)]) ...)`, for example with respect to cons cells?

---

<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 31, 2022, 2:14pm UTC](https://racket.discourse.group/t/futures-and-garbage-collection/1045/6 "2022-05-31T14:14:56Z")

</div>

The list will feature N separate allocations, and N-1 pointers, so GC traversal will take somewhat longer. It will take about 2N space. The fxvector will take about N space, and have no interior pointers, so it will take only constant time to traverse in the GC. A plain vector with fixnums in it will also take about N space, but the whole vector will be traversed by the GC.

---

<div class="post-metadata">

**Author:** ![Laurent.O](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/laurent.o/32/18_2.png) [@Laurent.O](https://racket.discourse.group/u/Laurent.O)\
**Post date:** [May 31, 2022, 4:45pm UTC](https://racket.discourse.group/t/futures-and-garbage-collection/1045/7 "2022-05-31T16:45:06Z")

</div>

Turning a few lists into \*vectors helped, along with using unsafe-fl operations, but not as much as I hoped:

```scheme
cpu: 207335 real: 3864 gc: 2600

```

I'll take it anyway.

If anyone has more advice, I'm happy to try a few things.
