Desempenho de IQueryable versus Dicionário
-
14-11-2019 - |
Pergunta
Estou armazenando em cache vários metadados estáticos em meu aplicativo na inicialização.É de um banco de dados e há vários relacionamentos de chave estrangeira.Estou procurando a melhor maneira de modelá-los.Acabei de começar com o LINQ.
É fácil para mim declarar uma classe
public class AllData {
public static IQueryable<libm_ColPurpose> IQ_libm_ColPurpose = libm_ColPurpose.All();
public static IQueryable<libm_ColType> IQ_libm_ColType = libm_ColType.All();
...
(Estou usando o SubSonic 3 para gerar minhas aulas, mas isso não vem ao caso).Então posso usar o IQueryable<T
> membros para ter acesso a tudo que eu quiser, por exemplo:
libm_ColType ct = AllData.IQ_libm_ColType.SingleOrDefault(x => x.ColTypeStr == this.DefaultJetColTypeStr);
Antes de usar IQueryable eu estava usando Dicionários para armazenar relacionamentos FK, então para imitar o código acima eu codificaria o seguinte a partir de uma lista preexistente<libm_ColType
> lista
Dictionary<string, libm_ColType> colTypeByColTypeStr = new Dictionary<string, libm_ColType>();
foreach (libm_ColType x in list) { rtn.Add(x.ColTypeStr, x); }
e então eu poderia usar
libm_ColType ct = colTypeByColTypeStr[this.DefaultJetColTypeStr];
OK, finalmente chegamos à questão!
A pesquisa de dicionário por ID é extremamente eficiente, porém a solução IQueryable é muito mais flexível e elegante.
Estou me perguntando quanto impacto no desempenho terei usando IQueryable.Suspeito que estou fazendo uma varredura linear da lista cada vez que a chamo, e isso realmente aumentará em relação às chamadas repetidas se houver muitos registros envolvidos.Seria ótimo se eu pudesse identificar colunas de valor único e gerar uma tabela hash e armazená-la em cache após a primeira pesquisa, mas suspeito que isso não fará parte da oferta.
Isso é um pouco complicado para mim em relação ao uso do LINQ.
Observe (vou repetir novamente) que NÃO estou puxando dados de um banco de dados, eles já estão na memória e estou consultando lá, então só estou interessado em procurar o IQueryable na memória<T
>.
Solução
IQueryable representa uma coleção em um armazenamento de dados, então você provavelmente não ter as coleções na memória.Se você deseja explicitamente coleções na memória, eu voltaria aos seus dicionários.Lembre-se de que isso não impede que você use consultas LINQ nos dados.