C# Pergunta de desempenho
-
19-09-2019 - |
Pergunta
Quandry é - qual dos dois seguintes métodos executa o melhor
Objetivo - Obtenha um objeto de wrapper de tipo (definido abaixo)
Critérios - velocidade sobre armazenamento
não. de registros - cerca de 1000 - cerca de 2000, no máximo 6k
Escolhas - Crie objeto em tempo real ou faça uma pesquisa de um dicionário
Velocidade de execução - chamada x vezes por segundo
NB - Preciso entregar o código de trabalho primeiro e depois optar por otimização.
Definições -
class Wrapper
{
public readonly DataRow Row;
public Wrapper(DataRow dr)
{
Row = dr;
}
public string ID { get { return Row["id"].ToString(); } }
public string ID2 { get { return Row["id2"].ToString(); } }
public string ID3 { get { return Row["id3"].ToString(); } }
public double Dbl1 { get { return (double)Row["dbl1"]; } }
// ... total about 12 such fields !
}
Dictionary<string,Wrapper> dictWrappers;
Método 1
Wrapper o = new Wrapper(dr);
/// some action with o
myMethod( o );
Método 2
Wrapper o;
if ( ! dictWrappers.TryGetValue( dr["id"].ToString(), out o ) )
{
o = new Wrapper(dr);
dictWrapper.Add(o.ID, o);
}
/// some action with o
myMethod( o );
Solução
O primeiro seria mais rápido, pois na verdade não está fazendo uma pesquisa, está apenas fazendo uma alocação simples e uma tarefa.
Os dois segmentos de código não são quase equivalentes. Em função, no entanto, porque o método 1 poderia criar muitas duplicatas.
Outras dicas
- Nunca otimize sem o perfil primeiro.
- Nunca perfil, a menos que o código não atenda às especificações/expectativas.
- Se você precisar perfilar este código, escreva -o de ambos os lados e compare -o com a carga esperada.
EDIT: Eu tento favorecer o seguinte otimização, a menos que o desempenho seja inaceitável:
- Simplicidade
- Legibilidade
- Manutenção
- Testabilidade
Eu (recentemente) vi código altamente otimizado que foi muito difícil de depurar. Eu o refatorei para simplificá -lo e executei testes de desempenho. O desempenho foi inaceitável, então eu o perfilava, encontrei os gargalos e otimizei apenas aqueles. Reestrei os testes de desempenho e o novo código foi comparável à versão altamente otimizada. E agora é muito mais fácil de manter.
Aqui está um grátis ferramenta de perfil.
Sem realmente testar, eu esperaria que o cache dos valores de campo no invólucro (ou seja, evitar todas as chamadas e elencos do toque) provavelmente teria mais impacto no desempenho.
Então, depois de armazenar em cache esses valores, você provavelmente desejará manter as instâncias de invólucro, em vez de recriá -los com frequência.
Assumindo que você é verdade Preocupado por (ei, isso acontece), então seu próprio invólucro pode ser melhorado. Você está fazendo pesquisas de campo por string. Se você vai fazer a ligação muito com o mesmo campo definido na linha, é realmente mais rápido armazenar em cache as ordinais e procurar por ordem ordinal.
É claro que isso é apenas se você realmente precisar se preocupar com o desempenho, e os casos em que isso faria a diferença são bastante raros (embora em dispositivos incorporados não seja tão raro quanto na área de trabalho).