Sobre otimização em aplicações .Net – Parte 3 (final?)

Continuando essa saga, espero que seja útil pra você jovem aprendiz que anseia por casos reais de otimização em um código aberto.

Cenário anterior:

Memory: 937mb
Gen 0:499
Gen 1:103
Gen 3:10

Enquanto estive removendo bugs do meu mod, e estudando o Livro do Konrad, Pro .NET Memory Management, se você não conhece, tente assistir a explicação em uma conferência sobre performance.

Crédito: Amazon.

Acabei exercitando nesse código do KMM, e não documentei de maneira prática as alterações, mas vou apresentá-las com a ausência do meu pensamento na hora.

Utilizando a técnica que apresentei na parte 2 fui iterando nos itens que foram apresentando maior impacto no GC e memória.
lista de alterações:

  • Remoção de uma lista de tags que não fazia mais sentido pro código.
  • Alteração de alguns setters para private afim de identificar quais classes eram passíveis de ser transformadas em structs.
  • Simplificação de algumas strings que estavam sendo concatenadas em apenas uma string (Agora estou lembrando do Crocco), mas já já eu uso a Span
  • dupliquei a parte que carrega algumas alterações dos mods, porém removi os pontos que não eram pertinentes para identificar os conflitos.
  • transformei mais algumas classes em Structs e adequei o código para inicializar os valores direto na struct.
  • simplificação para setar o valor de TripleInt
  • remoção de uma lista sem capacity que não estava sendo usada para nada, mas mesmo assim era populada.
  • alteração para setar o valor do filename em uma propriedade invés de sempre ficar chamando Path.GetFileName((…));

Bora pra parte de praxe o commit e o resultado:

O que achou?

não sei você, mas eu estou aqui:

Clap Applause GIF

sumarizando os resultados:

Gen 0: 187 redução de 84% comparando com 1217 do primeiro post
Gen 1: 72 redução de 79% comparando com 351 do primeiro post
Gen 3: 11 redução de 54% comparando com 24 do primeiro post
Tempo: 13179ms redução de 83% comparando com 77309ms do primeiro post.
Memória: 590mb redução de 37% comparando com 944 do primeiro post.

Apesar desses resultados muito bons…

Não me leve a mal, não é que acho o resultado insatisfatório, mas o problema aqui não é mais eficiência de código, apesar de ter espaço pra otimização.

Consideremos a frase de Lowell Arthur descrito em “Software Engineering: A Practitioner’s Approach” by Roger Pressman:
20 percent of the code has 80 percent of the errors. Find them; fix them!

O que quero dizer é que os 20% do código, até mais que isso foi otimizado, porém eu preciso resolver o armazenamento de informação e indexação ineficiente BY DESIGN

vamos compreender o cenário:

  • São mais de 300 mods
  • cada mod pode conter milhares de alterações.
  • usamos os arquivos base do jogo para identificar quais alterações foram feitas.
  • carregamos todos os mods, indexamos os conflitos e enviamos pra memória

Somente com esses pontos é explícito o próximo passo, precisamos indexar essas alterações quando não existirem em uma base de dados, caso exista e o arquivo foi alterado indexamos, do contrário apenas usamos o que está disponível desta forma utilizaremos o consumo de CPU de forma eficiente, já que uma vez que ele trabalhar pra processar os mods, o trabalho será recuperável.

Também ganharemos mais memória, já que poderemos então carregar os conflitos somente para o mod que for selecionado na tela.

Próximos passos

Meu processo de otimização neste cenário se mostra suficiente para o problema abordado,

continuarei trabalhando na otimização e indexação desses arquivos de forma eficiente.

acabei corrigindo o valores de ganho, porque eu acabei invertendo as imagens…. :facepalm:

continuarei documentando as decisões que fui tomando, tentarei trazer o brainstorm que posso ter tido.

Esteja curioso!

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *