Come si fa a passare un'enumerazione in modo coerente? - pagina 3

 
Alexey Navoykov:

Gli esempi mostrati qui (caso 1: valore di ritorno1; caso 2: valore di ritorno2; caso 3: valore di ritorno3... Una persona adeguata metterebbe tutti i valori in un array e otterrebbe semplicemente il valore richiesto in base al suo indice, e per il compito inverso userebbe la ricerca binaria.

Sono a due mani a favore di un bel codice con gli array. Ma scrivendo un NormalizeDouble più veloce di quello regolare, ho riscontrato un effetto ottimizzatore - la bella soluzione via const-array era molto più lenta della macchinosa soluzione switch-case. Ho lasciato la seconda variante perché NormalizeDouble è usato molto nel tester. Lo metto nell'indicatore e non guardo questo mostro. Ma i backtest girano più velocemente.
 
fxsaber:
Sono a due mani a favore di un bel codice con gli array. Ma quando ho scritto un NormalizeDouble più veloce di quello regolare, ho incontrato un effetto ottimizzatore - una bella soluzione via const-array era molto più lenta di una soluzione ingombrante via switch-case. Ho lasciato la seconda variante perché NormalizeDouble è usato molto nel tester. Lo metto nell'indicatore e non guardo questo mostro. Ma i backtest girano più velocemente.

Ricordo che una volta c'era un thread che discuteva di switch, dove gli sviluppatori parlavano solo dell'implementazione come ricerca binaria, che ovviamente è molto più lenta del semplice accesso tramite indice calcolato.Ma ora sembrano averlo fatto più saggiamente: se un passo è costante, l'indice viene calcolato, altrimenti viene eseguita la ricerca binaria. Naturalmente, l'implementazione nativa è sempre più veloce di quella wrapper.

Naturalmente, questo dipende dalle vostre priorità. Ma imho, se la velocità è così cruciale che sei pronto a inventare stampelle, allora dovresti rinunciare anche a OOP e MQL ;) Anche se sono sicuro che con una codifica corretta questa differenza di velocità non sarà così sostanziale. Nelle misure di test stai semplicemente facendo correre la funzione attraverso il ciclo milioni di volte. E lo usate in modo più razionale nel codice reale, vero?

 
Alexey Navoykov:

Ricordo che una volta c'era un thread che discuteva di switch, dove gli sviluppatori parlavano solo dell'implementazione come ricerca binaria, che ovviamente è molto più lenta del semplice accesso tramite indice calcolato.Ma ora sembrano averlo fatto più saggiamente: se il passo è costante, allora l'indice viene calcolato, altrimenti la ricerca binaria. Naturalmente, l'implementazione nativa è sempre più veloce di quella wrapper.

Il compilatore, se non è scemo, dovrebbe trasformare il const-array e l'unico tipo di riferimento ad esso dall'indice in codice switch.

Naturalmente, potrebbe essere necessario a seconda delle vostre priorità. Ma imho, se la velocità è così cruciale che sei pronto a inventare stampelle, allora dovresti rinunciare a OOP e MQL in generale ;) Anche se sono sicuro che con una codifica corretta la differenza di velocità non sarà così sostanziale. Nelle misure di test stai semplicemente facendo correre una funzione attraverso un ciclo milioni di volte. E nel codice reale lo si usa più razionalmente, vero?

La velocità non è cruciale, ma quando scrivo in modo irrazionale, mi sento abbastanza a disagio. Non usare affatto l'OOP non è razionale, ovviamente. Comunque, guarda i modesti sforzi in kodobase che hai steso e che non hai contato per molti giorni. Lì capirete dove sono apparse le stampelle sotto forma dello stesso NormalizeDouble. È il risultato di un fatto casuale da implementazioni a volte irrazionali degli sviluppatori.
 
fxsaber:
Il compilatore, se non è scemo, sarebbe stato obbligato a trasformare il const-array e l'unico tipo di riferimento ad esso per indice in codice switch.

Quindi l'array è solo un const? E la statica? E perché "switch code"? È un'operazione semplice: confronta il valore dell'indice con la dimensione dell'array/enum, e se è inferiore, ottieni l'indirizzo dell'elemento richiesto come indirizzo dell'array + indice, e poi leggi il valore da lì. Ho pensato che tali sciocchezze devono essere compilate allo stesso modo.

Comunque, guardate i modesti sforzi in kodobase, che ho steso e non ho contato per molti giorni. Lì capirete dove sono apparse le stampelle sotto forma di quello stesso NormalizeDouble. È il risultato di un fatto accidentale da implementazioni a volte irrazionali degli sviluppatori.
E a proposito, quanto tempo fa avete fatto questi confronti? Forse il compilatore era ancora "muto" allora?
 
Alexey Navoykov:

Quindi l'array è solo un const? E la statica? E perché "switch code"? È un'operazione semplice: confronta il valore dell'indice con la dimensione dell'array/enum, e se è inferiore, ottieni l'indirizzo dell'elemento richiesto come indirizzo dell'array + indice, e poi leggi il valore da lì. Ho pensato che queste sciocchezze devono essere compilate allo stesso modo.

Non ricordo con certezza se si possono creare array statici usando metodi const - certamente no. Per una questione di principio, stavo facendo delle costanti e non delle statiche. Contando sull'intelligenza del compilatore. Dopo la compilazione, non ci sarebbe dovuto essere nessun accenno di array nelle viscere. Uno statik è una struttura molto più complicata di const, quindi ero sicuro che il compilatore non sarebbe riuscito a gestire lo statik. Ma dovrei fare un tentativo.

Non ho capito bene quali "sforzi" intendi. E a proposito, quanto tempo fa hai fatto questi confronti? Forse il compilatore era ancora "muto" allora?
Lo sforzo sarà visibile non appena uno dei moderatori preme qualche pulsante e dà il via libera alla pubblicazione del codice in kodobase. Ho fatto una soluzione conveniente per me stesso, non pensando alle prestazioni, e si è rivelata essere quasi un ordine di grandezza migliore nella build 1383 a 32 bit.
 
fxsaber:

Non ricordo esattamente se gli array statici possono essere resi const. metodi - sicuramente no. Per principio, stavo facendo delle costanti, non delle statiche. Contando sull'intelligenza del compilatore. Dopo la compilazione, non ci sarebbe dovuto essere nessun accenno di array nelle viscere. Uno statik è una struttura molto più complicata di const, quindi ero sicuro che il compilatore non sarebbe riuscito a gestire lo statik. Ma dovrei fare un tentativo.

Oh, bene, questo spiega tutto. Non dovresti fare affidamento sull'eccessiva intelligenza del compilatore, che ottimizza ulteriormente una soluzione mal progettata per te. Se tu stesso sei troppo pigro per farlo correttamente, dicendo che "la statica è molto più complicata" (anche se cosa sia complicato lì, non capisco), allora perché accusare il compilatore?

 
Alexey Navoykov:

Oh, bene, questo spiega tutto. Non dovresti fare affidamento sull'eccessiva intelligenza del compilatore, perché ottimizzerà una soluzione mal progettata per te. Se tu stesso sei stato troppo pigro / non hai pensato di farlo correttamente, dicendo "la statica è molto più complicata" (anche se cosa è complicato lì, non capisco), allora perché accusare il compilatore?

Ho aggiunto la statica all'array. Ha funzionato quasi tre volte più velocemente dello switch! Butta via quell'interruttore. Grazie per il suggerimento!
 
fxsaber:
Ho aggiunto la statica all'array. Ha funzionato quasi tre volte più velocemente dello switch! Cestinate questo interruttore. Grazie per il suggerimento!

Non c'è di che. Mi servirà da lezione per il futuro, che dovrei pensare 7 volte, prima di andare in giro a inventare stampelle).

Si scopre ora, che ho lodato l'interruttore, o meglio i suoi sviluppatori troppo presto. Così tutto è implementato lì attraverso la ricerca binaria solo, anche quando l'enumerazione va con multipli. Non va bene.

 
Alexey Navoykov:

Non c'è di che. Sarà una lezione per il futuro, pensare 7 volte prima di correre in giro a inventare stampelle )

Quasi quattro volte più veloce di NormalizeDouble standard (build 1395)... è una stampella degli sviluppatori.

 
fxsaber:
Quasi quattro volte più veloce di NormalizeDouble standard (build 1395)... è una stampella degli sviluppatori.

Tutti non sono senza peccato )