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.
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:
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!