Este artigo é uma tradução do artigo http://blog.marcocantu.com/blog/2018-delphi-rtl-improvements-rio.html
Mesmo sem bibliotecas inteiramente novas, a Delphi Run Time Library (RTL) tem visto muitas mudanças significativas em 10.3, principalmente focadas no desempenho.
Enquanto trabalhávamos nas atualizações do 10.2, começamos a nos aprofundar em alguns problemas de desempenho do Delphi RTL, que estavam afetando outras bibliotecas como processamento JSON, streaming, processamento de strings, serviços web DataSnap e RAD Server, e mais. Em muitos casos, resolver esses problemas exigia a adição de novos métodos a classes existentes ou a adição de novas funções globais, algo que podemos fazer apenas em versões de quebra de interface como a 10.3.
Otimização e desempenho foram um fator orientador para muitas das mudanças listadas abaixo, mas não o único elemento. Também queríamos atualizar bibliotecas externas, melhorar a conformidade com padrões como JSON e HTTP e melhorar a qualidade geral. Com este cenário em mente, a lista de melhorias é bastante longa (e um pouco chata, desculpe).
Mudança na estratégia de crescimento de estruturas de dados
Várias estruturas de dados (como TStringList, TList, TList <T>, TQueue <T> e TStack <T>) têm agora uma estratégia de crescimento flexível quando o armazenamento interno está cheio e precisa ser expandido após adicionar um item adicional. No passado, a estratégia era dobrar o tamanho da estrutura subjacente, algo que funciona bem para tamanhos menores, mas não quando você tem vários MB de armazenamento. Agora, as regras são aumentar a capacidade em 1,5 vezes. Por exemplo, você pode verificar um crescimento de TStringList marcando a propriedade Capacity, que agora cresce da seguinte forma (de 14K para 74K):
14.761
22.141
33.211
49.816
74.724
Esse comportamento, compartilhado por várias classes de coleção, é definido na nova função, declarada em SysUtils.pas:
function GrowCollection (OldCapacity, NewCount: Integer): Inteiro;
Agora, o elemento interessante é que a implementação pode ser substituída por uma estratégia de crescimento de função personalizada, gravando uma nova função compatível e chamando o procedimento global SetGrowCollectionFunc .
Alterações na classe TStringBuilder
A classe TStringBuilder teve várias mudanças com o objetivo de melhorar seu desempenho, incluindo uma mudança semelhante na estratégia de crescimento de memória, a remoção de algum código redundante e uma limpeza de implementação geral. O enumerador TStringBuilder foi otimizado, no entanto, espera que o objeto TStringBuilder não será modificado enquanto o enumerador está processando-lo (que é um comportamento comum para enumerações).
Há também um parâmetro adicional para o método TStringBuilder.ToString. A assinatura é ToString (UpdateCapacity: Boolean). ToString (True) dará melhor desempenho se nenhuma modificação for mais esperada para o TStringBuilder, já que reduz a quantidade de dados sendo copiados.
Aprimoramentos Relacionados a Listas
Existem outras melhorias relacionadas a listas e coleções. O TList genérico e o TDictionary genérico têm novas propriedades públicas para tornar seus comparadores (a definição de suas operações de comparação para classificação) acessíveis após a inicialização. Adicionamos um método TryAdd a TDictionary, um ExtractAt a TObjectList e melhoramos significativamente o desempenho de várias operações (IndexOf, Add e mais). Também otimizamos especificamente loops for-in para coleções genéricas e listas de strings, com um loop “for in” vazio cerca de 3 vezes mais rápido
Melhorias Relacionadas ao JSON
Em 10.3, aprimoramos a correção do conteúdo JSON, em termos do código JSON gerado pela classe TJSONValue e dos derivados, mas também em termos de análise. Também trabalhamos em melhorias de desempenho. Há uma nova classe TAsciiStreamWriter que pode ser combinada com um TJSONTextWriter para fornecer o melhor desempenho de geração de strings JSON (já que quase não faz nenhuma conversão). Existe agora a saída JSON “pretty print” com a introdução do novo TJSONAncestor.Format (Indentation: Integer = 4). Como conseqüência, o TJSON.Format foi descontinuado.
Também esclarecemos (e implementamos corretamente) a diferença entre chamar ToJSON e ToString para um objeto JSON:
- TJSONAncestor.ToJSON sempre produz uma string JSON formalmente válida
- TJSONAncestor.ToString produz uma string JSON similar, mas sem converter símbolos não ASCII para uNNNN (mais rápido, mas não formalmente válido)
O suporte de análise JSON tem um novo comportamento em caso de erros no texto de origem JSON, permitindo que você eleve uma exceção com informações sobre a posição de erro no texto de origem, em vez de apenas retornar nil . A nova opção que controla o comportamento é TJSONParseOption.RaiseExc . Se a exceção estiver ativada, ParseJSONValue gerará o novo System.JSON.EJSONParseException (que possui as propriedades Path, Offset, Line e Position). Além disso, o método TJSONObject.ParseJSONValue tem um terceiro novo parâmetro: RaiseExc, que substitui a configuração global fazendo com que a exceção seja levantada, no caso de erros de análise de JSON.
Melhorias na Classe TMemIniFile
No Delphi 10.3, otimizamos a implementação do TMemIniFile. Ler e construir um TMemIniFile é 10 a 25 vezes mais rápido e consome metade da memória. Outras operações TMemIniFile também foram aprimoradas e são 50 a 100% mais rápidas em comparação com a implementação anterior.
Também adicionamos a capacidade de carregar um TMemIniFile de um fluxo, com dois construtores sobrecarregados adicionais: TMemIniFile.Create (Stream) e TMemIniFile.Create (Stream, UseLocale). Esses parâmetros de construtores permanecem disponíveis na classe e são expostos em novas propriedades, Stream e UseLocale.
Atualizações de Bibliotecas Externas (zLib, PCRE, Unicode)
Fizemos algumas melhorias nas bibliotecas externas que incorporamos:
- O zlib foi atualizado para a versão 1.2.8 com correções adicionais (e agora é compilado com o compilador RAD Studio C ++ para 64 bits)
- O mecanismo de expressões regulares, PCRE, foi atualizado para 8.42 (e também agora compilado com o compilador RAD Studio C ++) e suporta a versão nativa UTF-16 no Windows (para reduzir as conversões de strings UTF-16 para strings UTF-8) .
- A tabela Unicode (unidade System.Character) suporta Unicode v11.0.
Muito foi feito em 10,3 para o Delphi RTL
Como você pode ver, o número de melhorias no Delphi RTL para o 10.3 Rio é bastante significativo, sem mencionar o trabalho focado na correção de erros e na melhoria da qualidade. Há mais para o HTTP e outras bibliotecas clientes, que abordarei em uma postagem de blog separada.