Efficient data structure similar to maxHeap

The genesis of my question is this problem from Leetcode.
I want a data structure that keeps values sorted without iterating over the whole structure on each update. I thought using a gb_tree would do the trick, but the implementation I came up with is actually slower than the naive recursive implementation I did using a list as the data structure. I suspect my gb_trees implementation is inefficient for logic reasons rather than structure reasons but can’t figure it out on my own. Are gb_trees a good structure for this use case? If so how might I improve my approach? If not, what alternatives would be better suited to the task?

List implementation (~275ms runtime):

  def last_stone_weight(stones) do
    stones
    |> Enum.sort(:desc)
    |> smash_sorted()
  end
     
  def smash_sorted([stone]), do: stone    
  def smash_sorted([x, y | stones]) do 
      [ abs(x-y) | stones]
      |> Enum.sort(:desc)
      |> smash_sorted()
  end

gb_trees implementation (~400ms runtime):

  def last_stone_weight(stones) do
    stones
    |> to_gb_tree()
    |> smash_heaviest_pair()
  end

  def to_gb_tree(stones) do 
    stones
    |> Enum.reduce(:gb_trees.empty(), fn stone, tree -> update_or_insert(stone, tree) end)
  end
  
   def smash_heaviest_pair(tree) do 
    if :gb_trees.is_empty(tree) do 
      0
    else
        {a, count, new_tree} = :gb_trees.take_largest(tree)
        case count do 
            2 -> smash_heaviest_pair(new_tree) 

            1 -> if :gb_trees.is_empty(new_tree) do 
                   a
                 else 
                    smash(a, new_tree) |> smash_heaviest_pair()            
                 end
            n -> :gb_trees.update(a, count - 2, tree) |> smash_heaviest_pair() 
        end
            
    end
  end
      
  def smash(a, tree) do 
      {b, count, new_tree} = :gb_trees.take_largest(tree)
    case count do 
        1 -> update_or_insert(a - b, new_tree)
        n -> update_or_insert(a - b, :gb_trees.enter(b, n - 1, tree))
    end
  end

  def update_or_insert(key, nil), do: update_or_insert(key, :gb_trees.empty())    

  def update_or_insert(key, tree) do       
    case :gb_trees.lookup(key, tree) do 
      {_, val} -> :gb_trees.update(key, val + 1, tree)
      :none -> :gb_trees.enter(key, 1, tree)
    end
  end