Wednesday, September 17, 2025
De manipular timestamps a comparadores personalizados: uma história de performance
Quando você desenvolve no ambiente do WhatsApp e precisa de uma ordenação de conversas personalizada, precisa escolher: manipular os dados das conversas para caber na lógica de ordenação existente, ou implementar uma ordenação própria. Este post mostra como migramos de uma abordagem cara, que manipulava timestamps, para uma solução eficiente com um comparador personalizado.
O problema
Nosso sistema de gerenciamento de conversas precisava de uma lógica de ordenação personalizada, baseada em diferentes estados de prioridade, com requisitos de ordem específicos que não dava para atender só com a ordenação padrão por timestamp.

A ordem original é cronológica (ainda usada na visão 'All')
Primeira abordagem: manipular timestamps
No começo, alteramos os timestamps das conversas para aproveitar a ordenação existente:
Problemas
Os principais problemas dessa abordagem estavam ligados a performance, integridade dos dados, uso de memória e complexidade da restauração. Cada ordenação exigia gerar timestamps em O(n), o que deixava o processo bem mais lento. Ao mesmo tempo, os timestamps originais eram sobrescritos, comprometendo a integridade dos dados. Para contornar isso, era preciso guardar em cache os valores originais, o que aumentava o uso de memória. Por fim, restaurar a ordem original era caro e complexo, adicionando atrito desnecessário.
A solução: um comparador personalizado
Em vez de alterar os dados das conversas, usamos a propriedade _comparator da coleção:
A restauração é instantânea:

Visão Pending implementada com ordenação personalizada das conversas (em vez da cronológica)
Ganhos de performance
A nova abordagem trouxe ganhos claros de performance sem prejudicar a manutenção. Como os objetos de conversa não mudam, não há nenhuma mutação de dados, o que garante integridade e confiabilidade. A restauração ficou cerca de 50 vezes mais rápida, porque depende de trocar o comparador em O(1) em vez de restaurar timestamps em O(n). Também é eficiente em memória, já que não é preciso duplicar nem cachear nada. E, ao manter dados e lógica de ordenação separados, a solução fica muito mais fácil de manter e estender.
A lição
Quando seus requisitos não cabem no modelo de dados existente, resista à vontade de manipular os dados. Procure pontos de extensão do framework que permitam implementar o comportamento que você precisa sem comprometer a integridade dos dados. As soluções mais elegantes costumam trabalhar com o framework, e não em volta dele.
Às vezes a melhor otimização é não fazer o trabalho: neste caso, não manipular dados quando você pode manipular o comportamento.