Atualização de engenharia.
Photo Explorer, Constellations e um Mapsake mais rápido.
Duas funcionalidades ambiciosas de fotos levantaram a mesma questão: o Mapsake poderia fazer muito mais trabalho sem ficar mais lento? Uma nova suíte de testes de benchmark para simulador e dispositivo transformou a resposta em um trabalho de engenharia mensurável.
Uma versão de novos recursos e uma versão de engenharia.
Esta atualização introduz duas das experiências de fotos mais ambiciosas do Mapsake: Explorador de fotos, que torna uma grande biblioteca de mapas pesquisável, e Constelações, que descobre fios visuais entre lugares distantes.
Inclui também o recurso menos visível da versão: um conjunto de benchmark de desempenho permanente. Este conjunto encontrou imediatamente os caminhos compartilhados mais lentos, tornou as correções mensuráveis e deu ao aplicativo uma maneira de detectar quando trabalhos futuros os tornam mais lentos novamente.
O resultado oferece mais do que apenas funcionalidade. O Mapsake é significativamente mais rápido para converter grandes bibliotecas de fotos em locais, encontrar cidades próximas e planejar uma constelação.
Photo Explorer pesquisa no registro de viagens, não na galeria de fotos.
O Photo Explorer começa com os metadados compactos que o Mapsake já mantém para fotos mapeadas. Isso inclui localização, data, fonte, câmera, notas, altitude, velocidade, favoritos, capturas de tela, edições e a organização adicionada dentro do aplicativo.
O índice permanece no dispositivo. Uma pesquisa pode ser direta (Japão, 2024, iPhone, favoritos) ou formulada de forma mais natural, como "fotos favoritas da Itália do ano passado". A camada de consulta converte o idioma suportado em um conjunto estruturado de filtros, enquanto o vocabulário determinístico e a correção de erros fornecem uma opção de fallback confiável.
A pesquisa é apenas uma forma de acessar a biblioteca. As coleções exibem grupos úteis sem a necessidade de digitar; a área do mapa limita os resultados geograficamente; a linha do tempo os agrupa por data; as pesquisas salvas e recentes facilitam a repetição de perguntas. Favoritos, classificações, tags, rótulos e notas estão em um componente local para que organizar uma foto não altere ou carregue o original.
A escolha arquitetônica importante é que cada ferramenta compartilha a mesma instantânea indexada. As coleções, a linha do tempo, o mapa e a pesquisa de texto não reconstroem cada vez um mundo de fotos 82,000 do zero.
O índice é derivado, enquanto a organização pessoal é durável.
O Photo Explorer precisava de dois tipos de armazenamento com durações de vida muito diferentes. Os campos de pesquisa, como nomes de locais, ano de captura, câmera, altitude e fonte, podem ser reconstruídos a partir dos metadados existentes do Mapsake. Um favorito, uma nota privada, uma classificação, uma etiqueta ou uma cor foram escritos por uma pessoa e não podem ser tratados como dados de cache descartáveis.
Mapsake armazena a organização criada pelo usuário em um pequeno arquivo secundário, elegível para backup. O índice de pesquisa maior está no cache, não contém bytes de imagem, é excluído do backup e pode ser regenerado sempre que seu esquema muda. A digitalização de uma biblioteca ou a exclusão de dados derivados não apaga o trabalho que alguém dedicou à organização.
Essa divisão também tornou os backups mais honestos. Os backups sem perdas em formato JSON e HTML podem conter notas e organização, mas não se transformam silenciosamente em arquivos de fotos. As anotações do Apple Photos mantêm um identificador iCloud estável para que um backup restaurado possa reconectar a cópia local em outro dispositivo Apple; os identificadores de ativos Immich já são estáveis por sua natureza.
O primeiro ambiente de teste completo produziu um índice compactado de aproximadamente 12.4 MB para 82,000 fotos. Uma compilação geográfica completa levou 2.61 segundos no simulador de desenvolvimento, uma restauração posterior do disco levou 1.20 segundos, a geração de coleções levou 126 milissegundos e o modelo de linha do tempo diário levou 211 milissegundos. Esses números atribuíram um orçamento próprio a cada parte do recurso em vez de esconder tudo atrás de uma medição genérica de "pesquisa".
O Photo Explorer também explica por que um item correspondeu. Um resultado pode indicar que correspondeu a Kyoto, 2024, uma câmera iPhone, uma nota privada ou um filtro selecionado. Essa pequena linha é importante quando uma consulta combina linguagem natural com vários controles exatos: o usuário nunca deve ter que adivinhar o que o mecanismo de pesquisa quis dizer.
A linguagem da pesquisa é uma interface, não uma licença para improvisar.
Cada consulta suportada se torna, em última análise, uma estrutura de filtro validada. O caminho direto reconhece locais, datas, fontes, modelos de câmera, notas, favoritos, classificações, tags, altitude, velocidade, capturas de tela e fotos editadas. Um corretor ortográfico limitado pode corrigir palavras de intenção e vocabulário indexado conhecido, mas não reescreve notas privadas arbitrárias.
Em dispositivos que suportam os modelos de base on-device da Apple, o texto enviado também pode ser interpretado na mesma estrutura restrita. Apenas a consulta e o ano atual são fornecidos a esse modelo do sistema. Os pixels da foto, os índices de metadados, as notas de localização e a organização pessoal nunca são fornecidos. Intervalos inválidos e valores desconhecidos são rejeitados e o analisador determinístico permanece a solução de fallback.
A interface mostra a interpretação e oferece um caminho de volta para as palavras originais. Este é um lugar onde a inteligência é útil apenas quando permanece verificável. "Fotos a 3,000 metros do ano passado" devem parecer conversacionais, mas ainda devem se comportar como um conjunto preciso de filtros.
Constellations procura repetições através da distância.
"Then & Now" pergunta se alguém retornou ao mesmo local. "Constellations" pergunta quase o oposto: quais ideias visuais ele repetiu em lugares distantes?
O índice local extrai um conjunto compacto de sinais visuais e motivos das fotos de viagem elegíveis. O planejador procura características que sejam distintivas de uma imagem, em vez de simplesmente comuns em todos os lugares, e, em seguida, conecta os candidatos de diferentes destinos. Portas, costas, silhuetas, formas de montanhas, cores, estações e composição podem se tornar o vocabulário de um tópico.
Esses threads são organizados em um céu tridimensional. O usuário pode navegar por ele, abrir uma constelação, manter ou descartar uma conexão e reproduzir um filme de corte em que as fotos relacionadas se dissolvem de um lugar para outro. Os cartões de compartilhamento e o reel usam os mesmos dados de thread salvos.
A extração e o planejamento ocorrem no dispositivo. O Mapsake não envia uma biblioteca de viagens para um serviço de análise de imagens. Os lotes em segundo plano podem aprofundar o índice ao longo do tempo sem que o primeiro lançamento precise esperar que toda a biblioteca seja carregada.
O índice visual foi projetado para ser retocado de forma barata.
Para cada entrada elegível, o Mapsake executa uma pequena decodificação de imagem e deriva vários sinais: uma impressão de recursos Vision, rótulos de classificação brutos, uma paleta de cores compacta e uma classe de luz estimada a partir da localização, hora e elevação solar. A impressão de recursos é uma descrição numérica usada para a similaridade; não é uma cópia da imagem e não pode ser exibida como tal.
O índice armazena identificadores de classificadores brutos em vez de substituí-los imediatamente por motivos orientados ao produto. Essa escolha rendeu bons resultados durante os testes com bibliotecas reais. A primeira lista de motivos incluiu rótulos que pareciam razoáveis, mas que na verdade não estavam presentes na taxonomia suportada pelo Vision. Como os rótulos brutos ainda estavam disponíveis, a reconstrução de "Torres e pontes", "Barcos e portos" e grupos de motivos posteriores foi uma avaliação rápida em vez de outra varredura de milhares de originais.
A indexação começa com fotos representativas em vez de ler estritamente a biblioteca da mais recente para a mais antiga. As fotos são agrupadas em células de localização aproximadas e dias de localização, com preferência por imagens estáticas úteis e espaçamento entre sequências. O planejador então percorre os locais em ciclos. Isso fornece uma ampla cobertura geográfica no início, enquanto os processos em segundo plano adicionam gradualmente profundidade.
A primeira versão escolheu uma foto por local em cada rodada. Dados reais de dispositivos revelaram a falha: a maioria dos locais permaneceu abaixo do mínimo de três fotos usado pelo motor de threads, então milhares de ativos indexados ainda poderiam não produzir candidatos. Dividir cada rodada em três representantes tornou o índice útil mais cedo sem aumentar seu orçamento total. Isso é precisamente por que ambientes de teste sintéticos e uma biblioteca real e desorganizada são importantes.
O extrator funciona em lotes sequenciais, executa as alterações de forma atômica, pausa em caso de estresse térmico e ignora a extração em segundo plano no modo de baixo consumo. As miniaturas do Apple Fotos que já estão no dispositivo são tentadas primeiro; as imagens que estão disponíveis apenas no iCloud podem esperar uma passagem posterior com conexão de rede. O Immich usa a mesma pipeline visual do seu cliente de miniaturas existente.
A semelhança por si só não conta uma história.
Uma distância de recurso pode encontrar duas fotografias visualmente semelhantes, mas o Constellations é projetado para encontrar uma conexão entre lugares em vez de um detector de duplicatas. As fotos candidatas devem pertencer a destinos a pelo menos 150 quilômetros de distância. O mecanismo também considera motivos distintos, iluminação incomum, estação e rituais de calendário recorrentes antes de admitir uma conexão.
“Distintivo” se tornou a parte difícil. Um modelo de pontuação inicial recompensava sinais que existiam em ambos os lugares. Na biblioteca de desenvolvimento, isso gerou centenas de conexões dominadas pela noite e pelas estações comuns. Esses sinais eram tecnicamente compartilhados, mas não surpreendentes. O mecanismo agora avalia a relevância: um sinal é importante quando é excepcionalmente forte em ambos os lugares em comparação com a biblioteca da pessoa como um todo.
Isso mudou a pergunta de "Ambos os locais contêm fotos noturnas?" para "Ambos os locais têm uma quantidade incomumente alta de fotos noturnas para esta biblioteca?". Os sinais comuns desaparecem em segundo plano, enquanto as capturas repetidas durante a "hora azul", as vistas das portas, os portos, a luz de inverno ou uma semana de férias recorrente podem se tornar significativas.
Os candidatos visuais usam vários representantes por local em vez de um único par aleatório. Os identificadores de thread são derivados de sua localização e família, portanto, a mesma conexão mantém sua identidade após uma nova avaliação. O status 'salvo', 'rejeitado' e 'visto' permanece, e um thread rejeitado não reaparece simplesmente porque o mecanismo foi executado novamente.
O layout do céu também é pré-calculado e determinístico. As posições geográficas definem os nós, a força da conexão atrai os lugares conectados uns aos outros, e um pequeno jitter aleatório evita sobreposições exatas. A interface em tempo real pode animar entre uma geografia semelhante a um globo e a constelação final com um único valor de transição; ela não executa uma simulação de física que consome muita bateria a cada quadro.
O corte de filme usa a atenção de saliência da Vision para posicionar o movimento suave da câmera ao redor da parte importante de cada exemplo. Uma porta se dissolve em outra porta em vez de alinhar cegamente dois centros de imagem. "Reduzir o movimento" remove o movimento de deriva e encurta a transição, enquanto um recorte central é o método de fallback elegante quando a saliência não está disponível.
Por que criar uma suíte de testes agora?
O desempenho de uma biblioteca grande havia atingido um ponto em que a intuição já não era suficiente. Uma alteração pode fazer com que uma tela pareça mais rápida, enquanto silenciosamente torna as importações, as memórias ou as constelações mais lentas, porque todos dependem dos mesmos processos geográficos e de fotos.
O novo conjunto tem duas vias:
- Um motor de lógica executa testes de funcionalidades determinísticas em conjuntos de dados pequenos, médios e de estresse, incluindo um nível de foto 82,000 com base no relatório do mundo real mais abrangente disponível durante o desenvolvimento.
- Uma camada da interface do usuário exibe telas representativas, enquanto a instrumentação de desempenho da Mapsake registra o tempo de execução, problemas e memória.
Os benchmarks usam a otimização da versão de lançamento com a capacidade de teste habilitada. As compilações de depuração são intencionalmente excluídas porque o Swift não otimizado produz números que não são relevantes para o aplicativo publicado. Os resultados do simulador e do dispositivo físico também mantêm linhas de base separadas para que o hardware diferente não seja comparado como se fosse o mesmo ambiente.
O pacote cobre o gazetteer, a geometria do mapa, as importações, os metadados das fotos, as conquistas, Passport, Amigos, backups, selos, constelações, memórias e o Photo Explorer. As redes em tempo real, a qualidade da câmera, a enumeração do sistema de fotos e o CloudKit permanecem testes de integração porque fingir que essas entradas são determinísticas tornaria os resultados menos honestos.
Um benchmark pode estar terrivelmente errado
A criação do conjunto exigiu mais esforço do que simplesmente integrar um cronômetro no código do aplicativo. O ambiente de teste inicial usava uma função hash simples para selecionar as coordenadas; o Swift randomiza deliberadamente esse hash entre os processos, o que altera a geometria em aproximadamente 30 por cento de uma execução para outra. Os ambientes de teste agora usam um gerador fixo, e o conjunto valida a forma gerada antes de aceitar um resultado.
Um cenário inicial chamado import.merge mediu novas inserções. O caminho de produção que deveria representar foi uma mesclagem idempotente em um atlas existente. O benchmark foi rápido e repetível, mas estava testando a coisa errada. Corrigir a configuração alterou a linha de base antes de qualquer tentativa de otimização.
As medições da interface do usuário apresentavam uma armadilha semelhante. Os contadores de desempenho eram acumulados desde o início, então um gesto de guia poderia herdar atrasos da animação de inicialização e parecer mais lento do que realmente era. Agora, cada interação limpa sua captura anterior e, em seguida, processa apenas o trabalho dentro do contexto desse cenário.
O ambiente de execução registra o sistema operacional, o nível de hardware, a versão, o estado térmico e o estado térmico. O resultado de uma simulação nunca é priorizado em relação a uma linha de base do dispositivo. As execuções térmicas não nominais permanecem como diagnósticos úteis, mas são anotadas em vez de causar uma falha de regressão. Uma regressão deve exceder tanto um limite relativo quanto um valor absoluto pequeno para que o ruído de alguns milissegundos não se torne uma emergência falsa.
Estes detalhes não são parte da burocracia relacionada ao benchmark. É o que torna esse número relevante.
Os mecanismos de correção encontraram um bug real no mapa
O teste mais útil na primeira fase de desempenho não mediu a velocidade. Ele comparou a derivação de fotos para locais otimizada com uma referência simples e congelada em coordenadas com muitos limites.
Essa proteção falhou antes mesmo que a otimização tivesse alterado o motor. As fotos dentro de polígonos administrativos sobrepostos (Berlim dentro da Brandemburgo, Seul dentro da Gyeonggi e Kyiv dentro de sua região circundante) poderiam ser atribuídas com base na ordem de iteração aleatória de um dicionário. A mesma coordenada poderia ser resolvida de forma diferente após um lançamento.
Tanto o mecanismo de referência quanto o de produção agora ordenam os candidatos sobrepostos por área do polígono, permitindo que a característica administrativa mais específica vença de forma determinística. Somente depois que as fotos de referência 82,000 não produziram diferenças, com caminhos quentes e frios concordando, os atalhos espaciais se tornaram aceitáveis.
Esta é a vantagem silenciosa da engenharia de desempenho com verificações de equivalência: pode descobrir um problema de correção que um trabalho de temporização normal nunca veria.
O que mudou nas primeiras medições.
O teste de estresse inicial revelou vários gargalos compartilhados. A primeira passagem de otimização adicionou a detecção de geometria indexada, um cache persistente de células geográficas, a resolução de locais memorizada, instantâneos compartilhados de fotos e atualizações incrementais da anotação do Atlas.
No simulador, a criação inicial de um mapa de foto 82,000 foi reduzida de 34.5 segundos para 8.0 segundos. Uma repetição comum após uma alteração de filtro ou ao abrir "Lugares" é 2.8 segundos. O planejamento de constelações no nível da foto de 10,000 falhou. 3.3 segundos para 0.9 segundos. O tempo de alternância de abas diminuiu em 31%, e os erros do paginador do Passport diminuíram em 47%.
A passagem subsequente substituiu as varreduras repetidas de bandas de latitude do SQLite por um índice de cidade mais próxima preguiçoso e ordenado por latitude e um cache de registros limitado. No simulador de benchmark, um lote de cidade mais próxima de tamanho médio caiu de 2.11 segundos para 5.2 milissegundos. Num iPhone físico, o mesmo motor partilhado falhou. 3.06 segundos para 6.35 milissegundos, enquanto o planejamento de constelações com níveis de estresse diminuiu de 5.60 segundos para 65.9 milissegundos.
Essa segunda iteração também melhorou a derivação de fotos 82,000 de 7.96 segundos para aproximadamente 1.00 segundos. no simulador, com uma inicialização a quente de 984 milissegundos. Os ganhos foram alcançados porque a pesquisa da cidade mais próxima está abaixo de imports, Then & Now, a derivação do mapa e as constelações, em vez de pertencer a uma única tela.
Estes são workloads de benchmark controlados, não uma promessa de que cada dispositivo ou biblioteca produzirá o mesmo número. O valor deles reside na comparabilidade: configurações fixas, estado térmico registrado, resultados definidos e mecanismos que podem detectar uma regressão significativa.
Mais rápido porque o trabalho se tornou mais reutilizável.
As maiores melhorias não vieram da remoção de recursos ou da adição de um indicador de carregamento. Elas vieram da interrupção do trabalho repetitivo:
- A geometria da região agora restringe os polígonos candidatos antes de realizar testes de pontos caros.
- Um cache geográfico de células, vinculado à compilação, memoriza as áreas resolvidas em várias execuções.
- A busca pela cidade mais próxima usa um índice espacial numérico em vez de reconstruir uma classificação do banco de dados para cada coordenada.
- As interfaces baseadas em fotos compartilham um instantâneo filtrado e imutável.
- Os pinos e bandeiras do atlas são atualizados por identificador em vez de serem removidos e recriados.
O Photo Explorer e o Constellations se beneficiam porque estão construídos sobre as mesmas bases. Isso também se aplica a importações, Then & Now, mapas de dados e histórias de lugares.
O código de referência é excluído dos arquivos da App Store, mas a prática permanece no repositório: execute a suite em torno de alterações em um caminho crítico, compare com a linha de base correta e mantenha o resultado. O desempenho é agora algo que o projeto pode testar, e não apenas algo que pode esperar notar.
Os números também preservam o trabalho inacabado. Uma implementação posterior da interface do usuário para dispositivos físicos atingiu um estado térmico crítico e ainda registrou um pico de memória significativo durante a troca de abas e quase um segundo de atraso ao abrir Constellations em comparação com a biblioteca real. Essas leituras são diagnósticas, não uma comparação de regressão limpa, mas mantê-las visíveis é mais útil do que declarar que o aplicativo está "completo".
O que esses três projetos têm em comum.
Photo Explorer, Constellations e o conjunto de testes começaram com a mesma restrição: uma vasta biblioteca de fotos deveria se tornar mais útil sem deixar o dispositivo ou tornar o restante do aplicativo mais lento.
Photo Explorer transforma metadados conhecidos em perguntas e coleções. Constellations transforma sinais de imagem representativos em uma história visual. O conjunto de testes garante que ambos funcionem com os mesmos motores subjacentes.
O recurso é visível em um resultado de pesquisa, um céu estrelado e um corte de transição. O trabalho de engenharia é visível principalmente no que não acontece: um upload não espera que todas as fotos de 82,000 sejam carregadas, um filtro não recria cinco cópias do mesmo array e um índice espacial rápido não altera silenciosamente a cidade à qual uma foto pertence.
Essa é a direção que quero dar ao trabalho de otimização no Mapsake. A velocidade não é uma fase de limpeza após ideias ambiciosas. É uma das ferramentas que tornam essas ideias seguras para serem mantidas.