Desempenho da utilização de métodos estáticos vs instanciar a classe que contém os métodos

StackOverflow https://stackoverflow.com/questions/202631

Pergunta

Eu estou trabalhando em um projeto em C #. O programador anterior não sabia programação orientada a objeto, de modo que a maior parte do código é em arquivos enormes (estamos falando em torno de 4-5000 linhas) distribuídos por dezenas e às vezes centenas de métodos, mas apenas uma classe. Refatoração um projeto como este é um empreendimento enorme, e então eu tenho semi-aprendi a viver com isso por agora.

Sempre que um método é usado em um dos arquivos de código, a classe é instanciado e, em seguida, o método é chamado na instância do objeto.

Eu estou querendo saber se existem quaisquer penalidades de desempenho notável em fazê-lo desta maneira? Devo fazer todos os métodos static "por agora" e, mais importante, será o benefício de aplicação a partir dele de alguma forma?

Foi útil?

Solução

A partir aqui , uma chamada estática é de 4 a 5 vezes mais rápido do que construir uma instância cada vez que você chamar um método de instância. No entanto, ainda estamos falando apenas de dezenas de nanosegundos por chamada, então é improvável que você notar qualquer benefício a menos que você tem laços muito estreitos chamar um método milhões de vezes, e você poderia obter o mesmo benefício através da construção de um único fora instância esse ciclo e reutilizá-lo.

Uma vez que você tem que mudar a cada site de chamada para usar o método recém-estático, você é provavelmente melhor gastar o seu tempo na refatoração gradualmente.

Outras dicas

Eu tenho lidado com um problema semelhante onde eu trabalho. O programador antes de me criou uma classe de controlador onde todas as funções BLL foram despejados.

Estamos redesenhando o sistema agora e criaram muitas classes do controlador, dependendo do que eles deveriam controlar por exemplo.

UserController, GeographyController, ShoppingController ...

Dentro de cada classe de controlador que têm métodos estáticos que fazem chamadas para cache ou o DAL usando o padrão Singleton.

Esta nos deu 2 vantagens principais. É um pouco mais rápido (cerca de 2-3 vezes mais rápido, mas estávamos falando nanossegundos aqui; P). A outra é que o código é muito mais limpo

i

ShoppingController.ListPaymentMethods()

em vez de

new ShoppingController().ListPaymentMethods()

Eu acho que faz sentido para métodos estáticos uso ou classes se a classe não mantém qualquer estado.

Depende do que outra coisa que objeto contém - se o "objeto" é apenas um monte de funções, em seguida, provavelmente não é o fim do mundo. Mas se o objeto contém um monte de outros objetos, em seguida, instanciar ele vai chamar todos os seus construtores (e destruidores, quando é excluído) e você pode obter a fragmentação de memória e assim por diante.

Dito isto, não soa como o desempenho é o seu maior problema no momento.

Você tem que determinar os objetivos da reescrita. Se você quiser ter bom testável, código OO extensível e de fácil manutenção, então você pode tentar usar objetos e seus métodos de instância. Depois de tudo isso é Object Oriented programação de que estamos falando aqui, não Classe Programação Orientada.

É muito fácil de falsificar e / ou objetos fictícios quando você definir classes que implementam as interfaces e executar métodos de instância. Isso faz com que unidade completa testar rápida e eficaz.

Além disso, se você está a seguir bons princípios OO (veja SOLID em http: //en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29 ) e / ou padrões de projeto de uso você certamente vai estar fazendo um monte de instância com base, desenvolvimento baseado interface, e não através de vários métodos estáticos.

Como para esta sugestão:

Parece bobo para mim para criar um objeto só assim você pode chamar um método que aparentemente não tem efeitos secundários sobre o objeto (a partir de sua descrição Suponho que isso).

Eu vejo isso muito em lojas dot net e para mim isso viola o encapsulamento, um conceito-chave OO. Eu não deve ser capaz de dizer se um método tem efeitos colaterais por se ou não o método é estático. Bem como quebrar o encapsulamento Isso significa que você precisará estar mudando métodos de estática para exemplo, se / quando você modificá-los para ter efeitos secundários. Eu sugiro que você lê-se no Open / princípio fechado para um presente e ver como a abordagem sugerida, citado acima, trabalha com isso em mente.

Lembre-se que velho castanheiro, 'otimização prematura é a raiz de todos os males'. Eu acho que, neste caso, este meio não saltar através de aros usando técnicas inapropriadas (ou seja, Classe programação orientada) até que você sabe que tem um problema de desempenho. Mesmo assim depurar o problema e olhar para a mais adequada.

Os métodos estáticos são muito mais rápido e usa muito menos memória. Não é este equívoco que é apenas um pouco mais rápido. É um pouco mais rápido, enquanto você não colocá-lo em loops. BTW, alguns laços olhar pequeno, mas realmente não são, porque a chamada de método que contém o circuito é também um outro loop. Você pode dizer a diferença no código que desempenha restituição de funções. Um monte de memória menos é infelizmente verdade em muitos casos. Uma instância permite um fácil compartilhamento de informações com métodos irmã. Um método estático vai pedir as informações quando ele precisar.

Mas, como em carros de condução, velocidade traz responsabilidade. Os métodos estáticos geralmente têm mais parâmetros do que o seu homólogo instância. Porque uma instância iria cuidar de cache variáveis ??compartilhadas, seus métodos de instância ficará mais bonita.

ShapeUtils.DrawCircle(stroke, pen, origin, radius);

ShapeUtils.DrawSquare(stroke, pen, x, y, width, length);

VS

ShapeUtils utils = new ShapeUtils(stroke,pen);

util.DrawCircle(origin,radius);

util.DrawSquare(x,y,width,length);

Neste caso, sempre que as variáveis ??de instância são usados ??por todos os métodos na maioria das vezes, os métodos de instância valem muito isso. Instâncias não são de estado sobre, é sobre compartilhar Embora comum ESTADO é uma forma natural de partilha, eles não são os mesmos. regra geral é esta: se o método está intimamente ligado com outros métodos --- eles se amam tanto que quando um é chamado, o outro precisa ser chamado também e eles provavelmente compartilhar o mesmo copo de água-- -, deve ser feita instância. Para traduzir métodos estáticos em métodos de instância não é tão difícil. Você só precisa tomar os parâmetros compartilhados e colocá-los como variáveis ??de instância. O outro caminho é mais difícil.

Ou você pode fazer uma classe de proxy que irá preencher os métodos estáticos. Embora possa parecer a ser mais ineficiente na teoria, prática conta uma história diferente. Isto porque sempre que você precisar chamar um DrawSquare uma vez (ou em um loop), você ir direto para o método estático. Mas sempre que você está indo usá-lo mais e mais, juntamente com DrawCircle, você vai usar o proxy instância. Um exemplo é o System.IO aulas FileInfo (instância) vs Arquivo (estático).

Os métodos estáticos são testáveis. Na verdade, ainda mais testável do que instância uma vez. Método getSum (x, y) seria muito testável não apenas para teste de unidade, mas teste de carga, teste integrado e teste de uso. métodos de instância são bons para testes de unidades, mas horrível para todos os outros testes (que é mais importante do que os testes unidades BTW) é por isso que temos tantos erros estes dias. A única coisa que faz com que todos os métodos não testável são parâmetros que não fazem sentido como (Sender s, EventArgs e) ou o estado global como DateTime.Now. Na verdade, os métodos estáticos são tão bons em capacidade de teste que você vê menos bugs no código C de uma nova distro Linux do que o seu programador médio OO (ele é cheio de s *** eu sei).

Eu acho que você parcialmente respondeu a esta pergunta na maneira que você pediu-lo:? Há qualquer perceptível penalidades de desempenho no código que você tem

Se as penalidades não são perceptíveis, você não precisa necessariamente fazer nada. (Embora escusado será dizer a base de código beneficiaria dramtically de um refactor gradual em um modelo OO respeitável).

Eu acho que o que estou dizendo é, um problema de desempenho é apenas um problema quando você perceber que isso é um problema.

Parece bobo para mim para criar um objeto só assim você pode chamar um método que aparentemente não tem efeitos secundários sobre o objeto (a partir de sua descrição Suponho que isso). Parece-me que um compromisso melhor seria ter vários objetos globais e apenas usá-los. Dessa forma, você pode colocar as variáveis ??que normalmente seria global para as classes apropriadas para que eles tenham espaço um pouco menor.

De lá você pode mover-se lentamente o alcance desses objetos a ser menores e menores até que você tenha um design OOP decente.

Então, novamente, a abordagem que I provavelmente usaria é diferente;).

Pessoalmente, eu provavelmente iria se concentrar em estruturas e as funções que operam sobre eles e tentar convertê-los em classes com membros pouco a pouco.

Quanto ao aspecto do desempenho da questão, métodos estáticos deve ser um pouco mais rápido (mas não muito), uma vez que não envolvem a construção, passando e desconstruindo um objeto.

Não é válido em PHP,
Objeto método é mais rápido:
http://www.vanylla.it/tests/static-method-vs -object.php

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