Lo splendore e la povertà dell'OLP - pagina 5

 
meat:

Qui, se ho capito bene, l'indice è definito tramite una ricerca binaria?

No, accesso diretto come in un array.

__________

Forse mi sono sbagliato, ci penserò.

In generale, nessuno vi impedisce di creare un array per l'intera dimensione del tipo e ottenere un accesso costante. (l'interruttore funziona solo con i tipi integrali).

Nel caso che hai descritto, è più conveniente inserire un'enumerazione.

 
TheXpert:

No, accesso diretto come in un array.

__________

Forse ho esagerato, ci penserò ancora.

In generale, nessuno vi impedisce di creare un array per l'intera dimensione del tipo e ottenere un accesso costante. (L'interruttore funziona solo con i tipi integrali).

Nel caso che hai descritto, sarebbe più conveniente creare un'enumerazione.

Per tutto il valore del tipo? Impossibile! In questo caso richiederà 16 Gb di memoria (per un array di tipo int) e che senso ha prendere il valore intero? Il calcolo della differenza tra il valore massimo e quello minimo sarà sufficiente. Ma questo è comunque un caso discutibile, perché per valori grandi bisogna prima negoziare con l'utente quanta memoria è disposto ad allocare per il programma. Questo è il motivo per cui è adatto solo per piccoli valori chiave (o meglio per una piccola differenza tra il massimo e il minimo). Questo lascia solo la ricerca binaria.

 
meat:

Questo lascia solo la ricerca binaria.

No, non ne avete bisogno. In breve, se avete bisogno della mappatura dei numeri in enum, avete bisogno della ricerca binaria, se lavorare con enum e la mappatura di enum in un numero è sufficiente, allora costante.

Capisco la memoria )), ecco perché ho scritto che ho esagerato.

 

c'è sempre spazio per la domanda - Perché? confrontare il grafico dello spread online e nel tester. Il tester non ha niente a che vedere con la realtà...

tol64:

Ha già dato una spiegazione più dettagliata (prova) da qualche parte?

Devi sostenere le tue affermazioni con delle prove, altrimenti non le guarderai nemmeno. ;)

 
C-4:
Ragazzi, leggete la documentazione dell'interruttore. Un buon interruttore è una transizione commutata le cui prestazioni non dipendono dal numero di scelte. 1 scelta, 100 o 1000 - il suo tasso di transizione sarà costante.
Wah grazie, buon riferimento, letto con piacere e beneficio.
 
dimeon:

c'è sempre spazio per la domanda - Perché? confrontare il grafico dello spread online e nel tester. Il tester non ha niente a che vedere con la realtà...

Per attirare l'attenzione. Aprite un nuovo thread e coprite la vostra domanda in modo più dettagliato. Mostra come nella realtà e come nel tester. Offri la tua soluzione a questo problema. Altrimenti rimarrà "senza possibilità e senza opzioni". )
 
Vinin:

Le prove verranno dall'altra parte. O di nuovo solo parole.

In generale, mi interessano solo i fatti.

Anche se so già che l'OOP è più lento, ma fornisce convenienze abbastanza concrete.

Come promesso, sto esponendo i risultati del profiling di un progetto. (Per favore perdonatemi, ma alcune funzioni sono oscurate, perché il codice non è per il pubblico generale).

Per cominciare dirò che questo è un vero progetto OOP, con una forte trasformazione dei dati sorgente. L'idea di usare OOP in esso è portata all'assoluto. Per esempio, non usa affatto le variabili globali, gli array, le funzioni al di fuori delle classi - perché non sono abbastanza OOP. Perché funzioni, abbiamo bisogno della storia degli ordini e degli affari eseguiti durante l'intero periodo. L'analisi di 6014 operazioni e 6599 ordini richiede solo 3,1 secondi o 0,25 millisecondi per transazione e la RAM per distribuire tutte le operazioni, ordini e posizioni richiede circa 13 MB, o in media 1 kilobyte per transazione. - Penso che questo sia un ottimo risultato per un'applicazione OOP:

2014.07.07 12:44:33.464 TestMA (AUDCAD,H1) Si comincia. L'analisi della storia delle transazioni (6014) e degli ordini (6599) è stata completata per 3,104 secondi. 13MB di RAM utilizzata.

Ma diamo un'occhiata alla struttura del tempo impiegato nell'inizializzazione dell'applicazione:

Vediamo che la maggior parte del tempo è speso per chiamare la funzione AddNewDeal. Questa è una funzione composta e il lavoro reale è delegato a RecalcValues (57%). A sua volta consiste in funzioni di sistema come HistoryOrderGetInteger:

Notate che i tempi di chiamata di queste funzioni sono approssimativamente uguali.

Notate che questa è la fine di tutto il trasportatore di funzioni. Prima di arrivare a questi calcoli è necessario passare un'altra dozzina di metodi OOP intermedi, e alcuni di essi sono anche virtuali. Ma il loro tempo di esecuzione è trascurabile e nel profiler sono nella seconda metà della lista.

Essendo un'applicazione 100% OOP, è molto facile per me tracciare le sezioni di codice critiche per il tempo, e posso trovare molto efficacemente nuovi modi per migliorare le prestazioni. So già che la parte rimanente (43%) è composta per l'80-90% da chiamate a CArray.Resize(). Ci sono alcuni punti in cui il codice non è ottimizzato e il ripartizionamento dell'array avviene più spesso del necessario. Potrei facilmente riscrivere questi moduli OOP e migliorare le prestazioni del 25%-30%. Senza OOP sarebbe più difficile perché ogni funzione è potenzialmente coinvolta in un numero infinito di interrelazioni e diventa molto più difficile calcolare le conseguenze dei cambiamenti in tale funzione.

Come risultato si scopre che anche un progetto OOP complesso può essere portato al limite delle prestazioni delle funzioni di base del sistema. Ma senza OOP sarà più difficile raggiungere tale produttività, perché ci saranno così tante funzioni che prima o poi si farà un errore: si faranno o chiamate inutili o gemelli non ottimizzati, o implementazioni troppo complesse e macchinose.

 
dimeon:

c'è sempre spazio per la domanda - Perché? confrontare il grafico dello spread online e nel tester. Nel tester non ha niente a che vedere con la realtà...

Forum sul trading, sistemi di trading automatico e test di strategia

La gloria e lo squallore dell'OOP

tol64, 2014.07.07 09:12

Per attirare l'attenzione. Apri un nuovo argomento e tratta la tua domanda in modo più dettagliato. Mostrate come è nella vita reale e come è nel tester. Suggerisci la tua soluzione a questo problema. Altrimenti rimarrà "senza possibilità e senza opzioni". )

+++

adimeon - Apri un thread, imparerai un sacco di argomenti sul perché non può e perché dovrebbe.

 
C-4:

Come promesso, sto pubblicando i risultati del profiling di un progetto. (Senza offesa, ma alcune funzioni sono mascherate perché il codice non è per il pubblico generale).

...

Perché tutto questo? Non hai citato i codici delle tue funzioni (se non per contare qualche frammento strappato). Quindi cosa discutere? Qui il thread è specificamente sul confronto delle prestazioni della programmazione OOP e procedurale. E il fatto che le tue funzioni segrete presumibilmente eseguono qualche lavoro, delegano qualcosa da qualche parte, prendono un po' di tempo, e tu gestisci magistralmente tutto questo - naturalmente, siamo incredibilmente felici per te, ma a cosa serve questa informazione, se non vediamo i codici.

 
meat:

Qual è il punto di tutto questo? Non hai citato i codici delle tue funzioni (a meno che tu non conti qualche frammento strappato). Quindi cosa discutere? L'argomento qui è specificamente sul confronto delle prestazioni della programmazione OOP e procedurale. E il fatto che le tue funzioni segrete presumibilmente eseguono qualche lavoro, delegano qualcosa da qualche parte, prendono un po' di tempo, e tu gestisci magistralmente tutto questo - naturalmente, siamo incredibilmente felici per te, ma a cosa serve questa informazione, se non vediamo i codici.

Ha dimostrato che la chiamata diretta o la chiamata virtuale non hanno alcun effetto nei progetti reali.

Con l'esempio del profiling di un vero progetto OOP mostrerò che la sua performance al limite tende alla performance della chiamata di funzione di sistema

La stragrande maggioranza dei costi sono sostenuti nella chiamata delle funzioni di sistema, dove passa la maggior parte del tempo dei programmi MQL. I costi di organizzazione delle chiamate sono trascurabili rispetto al carico utile.

Motivazione: