# Performance batch processing Messages

**URL:** <https://discourse.elm-lang.org/t/performance-batch-processing-messages/5126>\
**Category:** Request Feedback\
**Created:** [February 3, 2020, 6:10pm UTC](https://discourse.elm-lang.org/t/performance-batch-processing-messages/5126 "2020-02-03T18:10:52Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![eimfach](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/eimfach/32/3247_2.png) [@eimfach](https://discourse.elm-lang.org/u/eimfach)\
**Post date:** [February 3, 2020, 6:10pm UTC](https://discourse.elm-lang.org/t/performance-batch-processing-messages/5126/1 "2020-02-03T18:10:52Z")

</div>

I have the following edge case:

- I am generating large lists of data to create a world map for a game
- The generation process is batch processing a least 1000-1500 Messages but it can be way more depending on the world map size
- Since it would block the main thread if I would do it synchronously, I subscribed to `Time.every 0 TakeMessageAndProccessIt` to process each message (not animation frame , this would be too slow - 60fps only). It takes about 6 seconds to process about 1400 Messages, and I noticed that about 4 Seconds of it, it is idle ! I understand why there is idle time, but why is it so much ? Should I process multiple Messages in each step (Problem is also that some Messages in the Batch use Cmd with `Random.generate` ) ?

Here a small footprint of my Performance Profile:

 ![Bildschirmfoto 2020-02-03 um 18.12.51](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/2X/5/5e0d2ab8cd24fd3ae21726d7c966c4af524fa91c.png)

Can you see the idle gaps ?  
So my question is: Is there a way to make this better ? I also thought of a Web Worker to process this long calculations …

These are my messages for each field in the map: (Except `DroppedGenerationDataForPerformance` , `SetCurrentEcoSystemType` , `SetBiomeList` , `EndStep` )

```auto
type GenerationStepMsg
    = DroppedGenerationDataForPerformance
    | SetCurrentEcoSystemType EcoSystemType
    | SetBiomeList (List Biome)
    | RollRandomCoordinate (List WorldSpace -> Random.Generator Int) (List WorldSpace)
    | RollRandomBiome (List Biome -> Random.Generator Int)
    | RollChunkTreesSubCoordinates (List.Nonempty.Nonempty Tree -> Random.Generator (List ScreenSpace))
    | RollChunkTreeTypes (List.Nonempty.Nonempty Tree -> Random.Generator (List TreeType))
    | AddChunkToGlobalList
    | DropPickedBiomeFromBiomeList
    | CreateChunk (EcoSystemType -> Biome -> WorldSpace -> Chunk)
    | CalculatePossibleCoordinates (List Chunk -> List WorldSpace)
    | EndStep

```

---

<div class="post-metadata">

**Author:** ![folkertdev](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/folkertdev/32/133_2.png) [@folkertdev](https://discourse.elm-lang.org/u/folkertdev)\
**Post date:** [February 3, 2020, 7:34pm UTC](https://discourse.elm-lang.org/t/performance-batch-processing-messages/5126/2 "2020-02-03T19:34:46Z")

</div>

So it seems likely here that messages don’t contain enough work, and the elm runtime has some maximum refresh rate.

How much of the messages are use `Random`? if that’s a lot, a possible partial solution is to keep track of the random seed manually, and use `Random.step` to synchronously get some randomness and continue processing without going through `update`.

---

<div class="post-metadata">

**Author:** ![eimfach](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/eimfach/32/3247_2.png) [@eimfach](https://discourse.elm-lang.org/u/eimfach)\
**Post date:** [February 3, 2020, 9:49pm UTC](https://discourse.elm-lang.org/t/performance-batch-processing-messages/5126/3 "2020-02-03T21:49:48Z")

</div>

Wow, yeah that made a great speedup. Thanks a lot ! I refactored to `Random.step` and am now processing a batch of 50 messages per update: The time went from 6000ms to 150ms !

---

<div class="post-metadata">

**Author:** ![joakin](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/joakin/32/171_2.png) [@joakin](https://discourse.elm-lang.org/u/joakin)\
**Post date:** [February 3, 2020, 10:47pm UTC](https://discourse.elm-lang.org/t/performance-batch-processing-messages/5126/4 "2020-02-03T22:47:51Z")

</div>

It may be worth mentioning that timeouts in the browser have a granularity of a few milliseconds. For some browsers it may be 4 or 1 but it is definitely not immediate.

window.requestIdleCallback and ports may be a better option for this.

---

<div class="post-metadata">

**Author:** ![rupert](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/rupert/32/1775_2.png) [@rupert](https://discourse.elm-lang.org/u/rupert)\
**Post date:** [February 4, 2020, 10:03am UTC](https://discourse.elm-lang.org/t/performance-batch-processing-messages/5126/5 "2020-02-04T10:03:06Z")

</div>

> [@eimfach](#):
>
> Since it would block the main thread if I would do it synchronously, I subscribed to `Time.every 0 TakeMessageAndProccessIt` to process each message

Rather than susbscribing to `Time.every 0` , just process some messages in your `update` then create a new `Cmd` to process some more. Use this code to create the messages:

```auto
Task.perform identity (Task.succeed TakeMessageAndProccessIt)

```

That will go faster (but still not 100% cpu), and allow the application to remain responsive. You can trade off responsiveness against larger batches of work - its not ideal and you will notice responsiveness suffer.

Something along these lines:

```elm
update msg model = 
    case msg of
        TakeMessageAndProcessIt ->
            case model.queue of
                [] -> (model, Cmd.none)
                _ -> (processNextBatch model
                     ,Task.perform identity (Task.succeed TakeMessageAndProccessIt))
        ...

```

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)\
**Post date:** [February 14, 2020, 10:03am UTC](https://discourse.elm-lang.org/t/performance-batch-processing-messages/5126/6 "2020-02-14T10:03:15Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
