Performance advise

Hi everyone, I am looking for suggestions to reduce cpu usage of my app.
I have a game similar to bingo.
I have cards that contains 4 rows one for the title and the others for the number cells
each row contains 9 cells 5 of them with numbers 4 empty
something like this

|        title          |
|empty|num|num|...      |
|...                    |

the rows that contain select numbers are highlighted

so I have something like this

type Card = 
    Card Int (List Int) (List Int) (List Int) -- Card id row1 row2 row3
    type alias Cards = List Card

drawCard:List Int -> Cards -> Element msg
drawCard selectedBalls = (\Card id r1 r2 r3 -> Element.column[][
        header id, (cell r1 selectedBalls) |> Element.row[] (cell r2 selectedBalls) |> Element.row[] (cell r3 selectedBalls) |> Element.row[]

cell:List Int->Int->Element msg
cell existingBalls num =
    if num == 0 then
        [ --styling

        String.fromInt num
        |> E.text
        |> center
        |> E.el
        [ Font.color <|
            if List.member num existingBalls then

            , Bg.color <|
                if List.member num existingBalls then


The code works just fine but the performance is horrible when the game starts to be faster the cpu usage skyrockets do you have any suggestions how can I refactor the thing or what can i do to increase the performance

Any chance you could hook up a demo? It’s kind of hard to say anything about performance in the abstract. Be sure to use --optimize too (which e.g. ellie won’t).

If not, maybe you can run a performance profile (from the browser devtools) to see where most time is actually spent: is it rendering, is it computation?

Something that I’d want to change is use a Set to store the data. List.member is less efficient than Set.member. If you must use List (e.g. to preserve ordering), a custom version of member for integers that optimizes the comparison might be faster.

Hi @folkertdev, I am optimizing and minimizing the thing and I thought about set but input order is important in my case so set is not really suitable
Almost everything in the devtools are about recalculation of the styles and painting

String.fromInt num
|> E.text
|> center
|> E.el
if List.member num existingBalls then
[ Font.color <| Color.white, , Bg.color <| ]
[ Font.color <|, , Bg.color <| Color.white ]

this seems to be taking too much time very often

You could use a Set and a List, put the value in both, one for order and one for testing member? Or is there some Set or Dict package with an insertion order preserving implementation (assuming insertion order is what you want)?

Also you call List.member twice in identical ways - the compiler could optimize that, but I’m not sure if it does. Can use a to manually optimize it:

    isMember = List.member num existingBalls
[ Font.color <| if isMember then Color.white else
, Bg.color <| if isMember then else Color.white

I think that’ll make a big difference. Because of how elm generates JS for comparisons, I think using this custom member function will be slightly better still

fasterIntMember : Int -> List Int -> Bool
fasterIntMember v list = 
    List.any (\a -> (a - v) == 0) list

@NikosEfthias The bottom-up view of the profile is usually more helpful. you sometimes have to expand a bit, and click on the source location to actually read the name of a definition. That view will tell you where most time is actually spent (the self-time column).

There is an insertion ordered dict here, but it does not have a member function - easy to add one though:


Better implementation here, ordered Dict and Set with member functions already:

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