Pergunta

Eu tenho uma prática de codificação questionável.

Quando preciso para percorrer uma pequena lista de itens cujo limite de contagem está sob 32000, eu uso Int16 para o meu i tipo de variável em vez de Integer. Eu faço isso porque eu assumo usando o Int16 é mais eficiente do que um Integer desenvolvido.

Estou errado? Será que não há diferença de desempenho eficaz entre utilizando um Int16 vs um Integer? Devo parar de usar Int16 e ficar com Integer para todos os meu contando / iteração necessidades?

Foi útil?

Solução

De acordo com o abaixo de referência, o tempo de execução otimiza o desempenho de Int32 e recomenda-los para contadores e outras operações freqüentemente acessados.

Do livro: MCTS Self-Paced Training Kit (exame 70-536): Fundação Microsoft® .NET Framework 2.0-Application Development

Capítulo 1: "Framework Fundamentos"
Lição 1: "Usando tipos de valor"

Melhores Práticas: desempenho Otimizando com built-in tipos

O tempo de execução otimiza o desempenho de tipos inteiros de 32 bits (Int32 e UInt32), então usar esses tipos de contadores e outras variáveis ??integrais freqüentemente acessados.

Para as operações de ponto flutuante, duplo é o tipo mais eficiente porque essas operações são otimizados por hardware.

Além disso, a Tabela 1-1 na mesma seção lista recomendada usos para cada tipo. Relevantes para essa discussão:

  • Int16 - interoperação e outros usos especializados
  • Int32 - Números inteiros e contadores
  • Int64 - grandes números inteiros

Outras dicas

Você deve quase sempre uso Int32 ou Int64 (e, não, você não obter crédito usando UInt32 ou UInt64) quando percorrer uma matriz ou coleção pelo índice.

A razão mais óbvia que é menos eficiente é que todos os índices de array e coleta encontrada nas Int32s BCL tomar, por isso uma conversão implícita é sempre vai acontecer no código que tenta usar Int16s como um índice.

A razão menos óbvia (e a razão que as matrizes ter Int32 como um índice) é que a especificação CIL diz que todos os valores de operação de pilha são quer Int32 ou Int64. Toda vez que você quer carregar ou armazenar um valor para qualquer outro tipo inteiro (Byte, SByte, UInt16, Int16, UInt32, ou UInt64), há uma operação de conversão implícita envolvidos. tipos não assinados têm nenhuma penalidade para o carregamento, mas para armazenar o valor, isso equivale a um truncamento e uma possível verificação de estouro. Para os tipos assinados todas load sinal-estende, e cada loja sign-colapsos (e tem uma possível verificação de estouro).

O lugar que isso vai te machucar mais é o circuito em si, não os acessos da matriz. Por exemplo tomar este ciclo de aparência inocente:

for (short i = 0; i < 32000; i++) {
    ...
}

parece ser bom, certo? Não! Basicamente você pode ignorar a inicialização (short i = 0), uma vez que só acontece uma vez, mas a comparação (i<32000) e incrementando (i++) partes acontecer 32000 vezes. Aqui estão algumas pesudo-código para que essa coisa examina como o nível da máquina:

  Int16 i = 0;
LOOP:
  Int32 temp0 = Convert_I16_To_I32(i); // !!!
  if (temp0 >= 32000) goto END;
  ...
  Int32 temp1 = Convert_I16_To_I32(i); // !!!
  Int32 temp2 = temp1 + 1;
  i = Convert_I32_To_I16(temp2); // !!!
  goto LOOP;
END:

Existem 3 conversões lá que são executados 32000 vezes. E eles poderiam ter sido completamente evitado usando apenas um Int32 ou Int64.

Atualização: Como eu disse no comentário, tenho agora, de fato escreveu um post sobre este tema, . tipos de dados integrais rede e você

Int16 pode realmente ser menos eficiente porque as instruções x86 para o acesso palavra ocupam mais espaço do que as instruções para acesso DWORD. Vai depender do que o JIT faz. Mas não importa o que, é quase certo que não mais eficiente quando usado como a variável em uma iteração.

O oposto é verdadeiro.

bit inteiros

32 (ou 64) são mais rápidos que int16. Em geral, o tipo de dados nativo é o mais rápido.

Int16 são agradáveis ??se você quiser fazer seus dados-estruturas tão magra quanto possível. Isso economiza espaço e pode melhorar o desempenho.

Qualquer diferença de desempenho vai ser tão pequeno em hardware moderno, que para todos os efeitos, ele vai fazer nenhuma diferença. Tente escrever um par de equipamentos de teste e executá-los tanto algumas centenas de vezes, tomar o tempo médio de conclusão loop, e você verá o que quero dizer.

Pode fazer sentido a partir de uma perspectiva de armazenamento Se você tem muito recursos limitados -. Sistemas embarcados com uma pequena pilha, protocolos fio projetados para redes lentas (por exemplo, GPRS etc), e assim por diante

Nunca assuma eficiência.

O que é ou não é mais eficiente irá variar de compilador para compilador e plataforma para plataforma. A menos que você realmente testado isso, não há nenhuma maneira de dizer se int16 ou int é mais eficiente.

Gostaria apenas ficar com ints a menos que você se deparar com um problema de desempenho comprovado que o uso de Int16 correções.

Use Int32 em máquinas de 32 bits (ou Int64 em máquinas de 64 bits) para um desempenho mais rápido. Use um tipo de número inteiro menor Se você é realmente preocupado com o espaço que ocupa (pode ser mais lenta, embora).

Os outros aqui estão corretas, use apenas menos de Int32 (para código de 32 bits) / Int64 (para código de 64 bits), se você precisar dele para requisitos de armazenamento extremas, ou para outro nível da aplicação em um campo de objeto de negócios (você ainda deve ter propery validação nível neste caso, é claro).

E, em geral, não se preocupe com eficiência até que haja um problema de desempenho. E, nesse caso, o perfil dele. E se palpite e verificar com os dois lados, enquanto profiling não ajudar o suficiente, verifique o código IL.

Boa pergunta embora. Você está aprendendo mais sobre como o compilador faz a sua coisa. Se você quiser aprender a programar de forma mais eficiente, aprendendo o básico do IL e como o C # / VB compiladores fazer o seu trabalho seria uma ótima idéia.

Eu não posso imaginar que haja qualquer ganho significativo de desempenho em Int16 vs int.

Você economiza alguns bits na declaração da variável.

E definitivamente não vale a pena quando as especificações mudar e tudo o que você está contando pode ir acima de 32767 agora e você descobre que quando o aplicativo começa a jogar exceções ...

Não há nenhum ganho significativo de performance no uso de um tipo de dados menor que Int32, na verdade, eu li em algum lugar que o uso de Int32 será mais rápido do que Int16 por causa da alocação de memória

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top