Para continuar com as mudanças no PostGIS 3.1, neste post irei falar sobre as melhorias de desempenho em muitas funções que geram geometrias como binárias ou como texto.

1. Ponto flutuante para String

A base para esta mudança é o Ryū, um algoritmo desenvolvido por Ulf Adams que melhorou muito a velocidade de conversão de pontos flutuantes em string, que é provavelmente uma das funções mais usadas em sistemas. Pense em quantas vezes imprimimos números todos os dias: qualquer coisa, desde logs, relatórios, exibição em tela, ETLs, entre outras coisas… ou seja, melhorar uma função como essa significa uma redução direta na energia que usamos em nossos dispositivos e data centers.

Andrew Gierth trouxe as melhorias de algoritmo Ryū para o PostgreSQL 12 e Raúl Marín configurou para emulá-lo e fazer o mesmo no PostGIS.

2. O novo código

O novo código é baseado no Ryū permitiu então uma saída mais rápida e consistente do que antes. Vamos ver um exemplo da mesma geometria em diferentes níveis de precisão:





Podemos ver as duas mudanças mais visíveis aqui:

  • 0.29999999999999999 representa o mesmo valor binário que 0.3, portanto, em 3.1 sempre preferimos 0.3 como classificador e ainda mais seguro para uma viagem de ida e volta.
  • Na precisão 15, você já tem dígitos suficientes para mostrar 22.200000000000003, mas devido a um bug, não seriam exibidos até a precisão 17 no 3.0. Como é o caso 0.3, esse número já tem tantos dígitos quantos forem necessários para identificar exclusivamente um número de ponto flutuante binário, portanto, não há necessidade de adicionar mais dígitos em níveis de precisão mais altos.

Uma vez que você acelera a roda mais lenta no processo, outros aumentam em importância ou até mesmo se tornam o novo gargalo, então, além de apresentar Ryū e alterar o formato de saída das coordenadas, também foi necessário aplicar várias outras melhorias de desempenho:

  • Em muitas funções de saída, tanto em texto quanto em saída binária, agora geramos o buffer exato que iremos retornar ao PostgreSQL ao invés de um temporário que mais tarde precisa ser copiado para adicionar um cabeçalho.
  • Não usamos mais buffers intermediários ao imprimir coordenadas individuais para evitar chamadas memcpye strlen.
  • Em funções que precisam do SRS para a saída (como ST_AsGML ou opcionalmente ST_AsGeoJSON), foi armazenado em cache em vez de gerá-lo para cada linha. Também foi evitado SQL inlines onde o cache é destruído após cada linha, o que o torna inútil . Isso também afeta ST_GeomfromGeoJSON e o equivalente ‘{}’::geometry.
  • Também foram realizadas adaptações do custo das funções SQL para ajudar o planejador do PostgreSQL a tomar melhores decisões.

3. Comparações

Para a maioria dos benchmarks, foi utilizado o conjunto de dados Boundaries of Canada Provinces, que contém apenas 13 multipolígonos com uma média de 260 mil pontos e mais de 2.000 anéis.

Essas funções foram as menos afetadas pelas alterações, pois foram afetadas apenas por algumas das pequenas melhorias para evitar cópias desnecessárias. No entanto, vemos uma melhora de 4-9%:



Nas funções de saída de texto, vemos o impacto total de todas as alterações com funções que são 2 a 40 vezes mais rápidas do que na versão anterior. Veja:



Fonte: Engineering rocks