O esplendor e a pobreza da OLP - página 5

 
meat:

Aqui, tal como eu o entendo, o índice é definido através de uma pesquisa binária?

Não, acesso directo como numa matriz.

__________

Talvez eu estivesse errado, vou pensar no assunto.

Em geral, ninguém o impede de criar uma matriz para todo o tamanho do tipo e obter acesso constante. (o interruptor funciona apenas com tipos integrais).

No caso que descreveu, é mais conveniente inserir uma enumeração.

 
TheXpert:

Não, acesso directo como numa matriz.

__________

Talvez eu tenha exagerado, vou pensar de novo.

Em geral, ninguém o impede de criar uma matriz para todo o tamanho do tipo e obter acesso constante. (O interruptor funciona apenas com tipos integrais).

No caso que descreva, seria mais conveniente criar uma enumeração.

Para o valor total do tipo? Nem pensar! Neste caso, serão necessários 16 Gb de memória (para uma série de int). E para que serve tomar o valor total? O cálculo da diferença entre os valores máximo e mínimo será suficiente. Mas este é um caso questionável de qualquer forma, porque quando os valores são grandes, devemos primeiro negociar com o utilizador quanta memória está disposto a atribuir para o programa. É por isso que é adequado apenas para pequenos valores chave (ou melhor, para uma pequena diferença entre o máximo e o mínimo). Isto deixa apenas a pesquisa binária.

 
meat:

Isto deixa apenas a pesquisa binária.

Não, não é realmente necessário. Em suma, se precisar de mapear um número para um número, é necessária uma pesquisa binária. Se trabalhar com um número e mapear o número para um número é suficiente, então é necessária uma pesquisa constante.

Compreendo sobre a memória ), foi por isso que escrevi que exagerei.

 

há sempre espaço para a pergunta - Porquê? compare o gráfico de propagação online e no testador. O testador não tem nada a ver com a realidade...

tol64:

Já deu uma explicação mais detalhada (prova) algures?

Terá de fazer cópias de segurança das suas declarações com provas, caso contrário nem sequer olhará para elas. ;)

 
C-4:
Rapazes, leiam a documentação do interruptor. Uma boa comutação é uma transição cujo desempenho não depende do número de escolhas. 1 escolha, 100 ou 1000 - a sua taxa de transição será constante.
Wah obrigado, boa referência, lê-lo com prazer e benefício.
 
dimeon:

sempre espaço para a pergunta - Porquê? compare o gráfico de propagação online e no testador. O testador não tem nada a ver com a realidade...

Para chamar a atenção. Abra um novo fio e cubra a sua pergunta com mais detalhes. Mostrar como em real e como no provador. Ofereça a sua solução para este problema. Caso contrário, permanecerá "sem hipótese e sem opções". )
 
Vinin:

As provas virão do outro lado. Ou, mais uma vez, apenas palavras.

De um modo geral, só estou interessado em factos.

Embora eu já saiba que o OOP é mais lento, mas proporciona conveniências bastante concretas.

Como prometido, estou a traçar o perfil dos resultados de um projecto. (Perdoem-me, mas algumas funções estão apagadas, porque o código não é para o público em geral).

Para começar, direi que este é um verdadeiro projecto do OOP, com uma forte transformação dos dados de origem. A ideia de utilizar o OOP nele é levada ao absoluto. Por exemplo, não utiliza variáveis globais, matrizes, funções fora das classes - porque não são suficientemente OOP. Para que funcione, precisamos do histórico de encomendas e negócios realizados ao longo de todo o período. A análise de 6014 transacções e 6599 ordens leva apenas 3,1 segundos ou 0,25 milissegundos por transacção e a RAM para implantar todas as transacções, ordens e posições requer cerca de 13 MB, ou em média 1 kilobyte por transacção. - Penso que este é um resultado muito bom para uma aplicação OOP:

2014.07.07 12:44:33.464 TestMA (AUDCAD,H1) Estamos a começar. Parsing de negócios de história (6014) e encomendas (6599) concluídas durante 3.104 seg. 13MB RAM utilizados.

Mas vejamos a estrutura do tempo necessário para inicializar a aplicação:

Vemos que a maior parte do tempo é gasto a chamar a função AddNewDeal. Esta é uma função composta e o verdadeiro trabalho é delegado na RecalcValues (57%). Por sua vez, consiste em funções do sistema como HistoryOrderGetInteger:

Note-se que os tempos de chamada destas funções são aproximadamente iguais.

É de notar que este é o fim de todo o transportador de funções. Antes de se chegar a estes cálculos é necessário passar mais uma dúzia de métodos OOP intermédios, e alguns deles também são virtuais. Mas o seu tempo de funcionamento é insignificante e no perfilador estão na segunda metade da lista.

Como aplicação 100% OOP, é muito fácil para mim seguir as secções de código críticas em termos de tempo, e posso muito eficazmente encontrar novas formas de melhorar o desempenho. Já sei que a parte restante (43%) é 80-90% constituída por chamadas para CArray.Resize(). Há alguns lugares onde o código não é optimizado e a repartição das matrizes ocorre com mais frequência do que o necessário. Eu poderia facilmente reescrever estes módulos OOP e melhorar o desempenho em 25%-30%. Sem a OOP seria mais difícil de fazer porque cada função está potencialmente envolvida num número infinito de inter-relações e torna-se muito mais difícil calcular as consequências das alterações de uma tal função.

O resultado é que mesmo um projecto OOP complexo pode ser levado ao limite de desempenho das funções básicas do sistema. Mas sem OOP será mais difícil conseguir tal produtividade, porque haverá tantas funções que mais cedo ou mais tarde cometerá um erro: fará chamadas desnecessárias ou gémeos não optimizados, ou implementações demasiado complexas e incómodas.

 
dimeon:

há sempre espaço para a pergunta - Porquê? compare o gráfico de propagação online e no testador. No testador, não tem nada a ver com a realidade.

Fórum sobre comércio, sistemas de comércio automatizados e testes estratégicos

A glória e a miséria do OOP

tol64, 2014.07.07 09:12

Para chamar a atenção. Abra um novo tópico e cubra a sua pergunta com mais detalhes. Mostrar como é na vida real e como é no testador. Sugira a sua própria solução para este problema. Caso contrário, permanecerá "sem hipótese e sem opções". )

+++

àdimeon - Abra um fio, aprenderá muitos argumentos porque não pode e porque deve.

 
C-4:

Como prometido, estou a publicar os resultados de um projecto de perfil. (Sem desrespeito, mas algumas funções são mascaradas uma vez que o código não é para o público em geral).

...

Qual é o objectivo de tudo isto? Não citou códigos das suas funções (a menos que conte algum fragmento rasgado). Então, o que há para discutir? Este tópico é especificamente sobre a comparação do desempenho do OOP e da programação processual. E o facto de as suas funções secretas supostamente executarem algum trabalho, delegarem algo em algum lugar, demorarem algum tempo, e de o senhor lidar magistralmente com tudo isto - claro que estamos incrivelmente felizes por si, mas que bem fará esta informação, se não virmos os códigos.

 
meat:

Qual é o objectivo de tudo isto? Não citou códigos das suas funções (a menos que conte algum fragmento rasgado). Então o que há para discutir? O tópico aqui é especificamente sobre a comparação do desempenho do OOP e da programação processual. E o facto de as suas funções secretas supostamente executarem algum trabalho, delegarem algo em algum lugar, demorarem algum tempo, e de o senhor gerir tudo isto com maestria - claro que estamos incrivelmente felizes por si, mas que bem fará esta informação, se não virmos os códigos.

Mostrou que a chamada directa ou a chamada virtual não têm qualquer efeito em projectos reais.

Através do exemplo de traçar o perfil de um verdadeiro projecto OOP mostrarei que o seu desempenho no limite tende ao desempenho da função de chamada do sistema

A grande maioria dos custos são incorridos na chamada de funções do sistema, onde a maior parte do tempo os programas de MQL passam. Os custos de organização das chamadas são insignificantes em comparação com a carga útil.

Razão: