Pergunta

O sistema de trabalho I aqui foi escrito antes .NET 2.0 e não têm o benefício de genéricos. Ele acabou por ser atualizado para 2.0, mas nenhum do código foi reformulado devido a limitações de tempo. Há uma série de lugares onde o código usa ArraysLists etc. que armazenam as coisas como objetos.

Do ponto de vista do desempenho, o quão importante alterar o código para usar os genéricos? Eu sei de uma perspectiva perfomance, boxing e unboxing etc., é ineficiente, mas quanto de um ganho de desempenho vai realmente haver de mudar isso? São genéricos algo para uso em um go base para a frente, ou ele não o suficiente de uma mudança de desempenho que um esforço de consciência deve ser feito para atualizar código antigo?

Foi útil?

Solução

Tecnicamente, o desempenho dos genéricos é, como você diz, melhor. No entanto, a menos que o desempenho é extremamente importante e você já otimizados em outras áreas é provável que você fica muito melhor melhorias por gastar o seu tempo em outros lugares.

Gostaria de sugerir:

  • Use genéricos daqui para frente.
  • se você tiver testes de unidade sólida, em seguida, refatorar aos genéricos que você tocar código
  • passar outra vez fazendo refatorações / medição que irá melhorar significativamente o desempenho (chamadas de banco de dados, estruturas de dados mutáveis, etc) ao invés de alguns milissegundos aqui e ali.

É claro que há outros que o desempenho à mudança para os genéricos motivos:

  • menos propenso a erros, já que você tem a verificação em tempo de compilação de tipos
  • mais legível, você não precisa de lançar em todo o lugar e é óbvio que tipo é armazenado em uma coleção
  • se você estiver usando os genéricos vão para a frente, então é mais limpo para usá-los em todos os lugares

Outras dicas

Eis os resultados que obtive a partir de uma simples análise de uma seqüência de um arquivo de 100KB 100.000 vezes. A lista genérico (CHAR) levou 612.293 segundos para ir de 100.000 vezes através do arquivo. O ArrayList levou 2,880.415 segundos para ir de 100.000 vezes através do arquivo. Isto significa, em este cenário (como sua milhagem irá variar) A lista genérico (CHAR) é 4,7 vezes mais rápido.

Aqui está o código que percorreu 100.000 vezes:

Public Sub Run(ByVal strToProcess As String) Implements IPerfStub.Run
    Dim genList As New ArrayList

    For Each ch As Char In strToProcess.ToCharArray
        genList.Add(ch)
    Next

    Dim dummy As New System.Text.StringBuilder()
    For i As Integer = 0 To genList.Count - 1
        dummy.Append(genList(i))
    Next

End Sub

 Public Sub Run(ByVal strToProcess As String) Implements IPerfStub.Run
     Dim genList As New List(Of Char)

     For Each ch As Char In strToProcess.ToCharArray
         genList.Add(ch)
     Next

     Dim dummy As New System.Text.StringBuilder()
     For i As Integer = 0 To genList.Count - 1
         dummy.Append(genList(i))
     Next
 End Sub

A única maneira de saber com certeza é o seu perfil de código usando uma ferramenta como dotTrace.

http://www.jetbrains.com/profiler/

É possível que o boxe / unboxing é trivial em sua aplicação particular e não valeria a pena refatoração. Daqui para frente, você ainda deve considerar o uso de genéricos devido à segurança de tipos em tempo de compilação.

Os genéricos, seja Java ou .NET, deve ser usado para o projeto eo tipo de segurança, não para o desempenho. Autoboxing é diferente de genéricos (objeto essencialmente implícita às conversões primitivos), e como você mencionou, você não deve usá-los no lugar de um primitivo se há de ser um monte de operações aritméticas ou outras que causará um impacto no desempenho do repetido implícita a criação do objeto / destruição.

No geral, sugiro usar daqui para frente, e apenas atualizar o código existente se ele precisa ser limpo para a segurança Tipo / fins de projeto, não o desempenho.

Depende, a melhor resposta é o seu perfil de código e ver. I como AQTime mas uma série de pacotes existem para isso.

Em geral, se um ArrayList está sendo usado muito pode valer a pena mudar para uma versão genérica. Realmente, porém, é mais provável que você nem sequer seria capaz de medir a diferença de desempenho. Boxing e unboxing são passos extras, mas os computadores modernos são tão rápidas que não faz quase nenhuma diferença. Como um ArrayList é realmente apenas uma matriz normal com um bom wrapper, você provavelmente ver muito mais desempenho adquirida com a seleção melhor estrutura de dados (ArrayList.Remove é O (n)!) Do que com a conversão para genéricos.

Edit: Outlaw Programmer tem um ponto bom, você ainda será boxing e unboxing com os genéricos, apenas acontece de forma implícita. Todo o código em torno de verificar exceções e nulos de fundição e "é / como" palavras-chave ajudaria um pouco embora.

Os maiores ganhos, você vai encontrar nas fases de manutenção. Os genéricos são muito mais fácil lidar com e atualizar, sem ter que lidar com a conversão e problemas de fundição. Se este é o código que você continuamente visitar, em seguida, por todos os meios fazer o esforço. Se este é o código que não tenha sido tocado em anos, eu realmente não incomoda.

O que autoboxing / unboxing tem a ver com os genéricos? Esta é apenas uma questão de tipo de segurança. Com uma coleção não genérico, que são obrigados a voltar explicitamente convertido para tipo real de um objeto. Com os genéricos, você pode pular esta etapa. Eu não acho que há uma uma maneira diferença de desempenho ou de outra.

A minha antiga empresa realmente considerado este problema. A abordagem que tomámos foi: se é fácil de refatorar, fazê-lo; se não (ou seja, ele vai tocar muitas classes), deixá-lo para um momento posterior. Realmente depende se você tem ou não o tempo para fazê-lo, ou se existem itens mais importantes a serem codificação (ou seja, as características que você deve ser a implementação para clientes).

Então, novamente, se você não está trabalhando em algo para um cliente, vá em frente e passar refatoração tempo. Ele vai melhorar a legibilidade do código para si mesmo.

Depende de quanto está lá fora em seu código. Se você vinculativa ou exibir grandes listas na interface do usuário, você provavelmente ver um grande ganho em desempenho.

Se o seu ArrayList são apenas polvilhado aqui e ali, então provavelmente não seria um grande negócio apenas para obtê-lo limpo, mas também não iria afetar o desempenho geral muito.

Se você estiver usando um monte de ArrayLists em todo o código e seria um grande untertaking para substituí-los (algo que pode afetar seus horários), então você poderia adotar uma se-você-touch-it-change-lo aproximar-se .

A coisa principal é, porém, que os genéricos são muito mais fáceis de ler, e são mais estáveis ??em todo o aplicativo devido à forte digitação que você começa a partir deles. Você vai ver ganhos não apenas do desempenho, mas de maintainablity código e estabilidade. Se você pode fazê-lo rapidamente, eu diria que fazê-lo.

Se você pode obter buy-in do Product Owner, Eu recomendo a obter-lo limpo. Você ama seu código mais tarde.

Se as entidades nas ArrayLists são tipos de objeto, você vai ganhar um pouco de não lançando-os para o tipo correto. Se eles são tipos de valor (structs ou primitivos como Int32), então o processo de boxe / unboxing adiciona muita sobrecarga, e coleções de genéricos deve ser muito mais rápido.

Aqui está um artigo MSDN sobre o assunto

Os genéricos tem desempenho muito melhor, especialmente se você estará usando o valor do tipo (int, bool, struct etc.) onde você vai ganhar um ganho de desempenho noticeble.

  1. Usando ArrayList com valor tipos faz com que o boxe / unboxing que se feito várias centenas de vezes é substantialy mais lento, em seguida, usando a Lista de genéricos.

  2. quando armazenar valores de tipos de objeto que você vai até quatro memória vez por item. Embora este montante não irá drenar a RAM a memória cache que é menor poderia conter menos itens, o que significa que, enquanto repetindo uma longa coleções haveria muitas cópias da memória principal para a cache que iria atrasar a sua aplicação.

Eu escrevi sobre aqui .

Usando genéricos também deve significar que seu código será simples e fácil de usar se você quiser coisas alavancagem como linq nas versões mais tarde c #.

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