Posso fare un brainstorming su un'implementazione veloce per tradurre un array di strutture (lunghezza multipla di sizeof(int)) da e verso un array int[]?
L'applicazione pratica è lo scambio veloce di dati attraverso le risorse. La mia variante è troppo universale, quindi rallenta.
Queste funzioni sono apparse in MT5
StructToCharArray
CharArrayToStruct
Non esistono e probabilmente non esisteranno in MT4. Quindi dobbiamo risolvere il problema con e senza queste funzioni (se sono utili).
Il risultato sarà utile a un gran numero di utenti del forum qui.
Ho scritto un modello molto semplice per il brainstorming con la mia soluzione a questo problema.
// Решения задачи: https://www.mql5.com/ru/forum/287618/page14#comment_9806429#define BENCH(A) \
{ \
constulong StartTime = GetMicrosecondCount(); \
A; \
Print("Time[" + #A + "] = " + (string)(GetMicrosecondCount() - StartTime)); \
}
// Инициализация исходных данныхint InitData( MqlTick &Ticks[], constint Amount = 1 e6, constdouble Price = 1.2345)
{
constint Size = ArrayResize(Ticks, Amount);
for (int i = 0; i < Size; i++)
Ticks[i].bid = Price;
return(Size);
}
MqlTick TicksIn[]; // Массив с исходными данными.constint Init = InitData(TicksIn); // Инициализировали его.// Проверка, что два массива совпадают.bool IsCompare( constMqlTick &Ticks1[], constMqlTick &Ticks2[] )
{
constint Size = ArraySize(Ticks1);
bool Res = (Size == ArraySize(Ticks2));
for (int i = 0; (i < Size) && Res; i++)
Res = (Ticks1[i].bid == Ticks2[i].bid);
return(Res);
}
voidOnStart()
{
MqlTick TicksOut[];
int Array[];
BENCH(TicksToIntArray_fxsaber1(TicksIn, Array)); // Замерили конвертацию MqlTick[] -> int[].
BENCH(IntArrayToTicks_fxsaber1(Array, TicksOut)); // Замерили конвертацию int[] -> MqlTick[].Print(IsCompare(TicksIn, TicksOut)); // Убедились, что тики на входе и выходе совпадают.
}
// Варианты реализаций/***********************************************/#include <TypeToBytes.mqh> // https://www.mql5.com/ru/code/16280template <typename T1, typename T2>
int ArrayToArray( const T1 &Source[], T2 &Target[] )
{
return(_ArrayCopy(Target, Source) / sizeof(T2));
}
// Перевод массива тиков в массив int[].int TicksToIntArray_fxsaber1( constMqlTick &Ticks[], int &Array[] )
{
return(ArrayToArray(Ticks, Array));
}
// Перевод массива int[] в массив тиков.int IntArrayToTicks_fxsaber1( constint &Array[], MqlTick &Ticks[] )
{
return(ArrayToArray(Array, Ticks));
}
/***********************************************/
ZY Da un'esecuzione all'altra, ottengo risultati molto diversi. Per esempio, se cambio l'ordine dei Test, tutto viene quasi invertito. A quanto pare, ho bisogno di una misurazione della velocità più oggettiva.
Senza molta riflessione e debugging ho scritto la prima cosa che mi è venuta in mente, quindi ci possono essere molti difetti. Non ho mai incontrato un compito del genere (anche se ho lavorato molto con i sindacati).
ZZZ, ArrayCopy sembra essere un po' una seccatura.
Mi ricordo di aver misurato su qualche compito locale, dove dovevo copiare un piccolo numero di elementi. Fino a 16 elementi il ciclo for era molto più veloce di quello ArrayCopy, quando il numero di elementi era maggiore, quello ArrayCopy era più veloce. Naturalmente, la variante più veloce senza loop (come le mie funzioni nella pagina precedente)
Il mio punto è che for(int i=0; i<5; i++) dst[i]=src[i]; funziona più lentamente di dst[0]=src[0]; dst[1]=src[1]; dst[2]=src[2]; dst[3]=src[3]; dst[4]=src[4];
il che è abbastanza ovvio in vista delle operazioni aggiuntive relative al controllo del ciclo)
E CopyArray funziona molto più velocemente di entrambi, come ho controllato ora. Forse dipende dalla situazione, ovviamente.
E CopyArray, come ho controllato ora, funziona molto più velocemente di entrambe le opzioni, sembra. Forse dipende dalla situazione, naturalmente.
Se ArrayCopy() è fatta sul principio di Cish memmove(),
Penso che la velocità di ArrayCopy() dipenda dalla velocità di allocazione della memoria, se la memoria intermedia del buffer è pronta per la copia, ArrayCopy() sarà eseguita molto rapidamente, se la memoria non è allocata, si avvieranno richieste al sistema operativo per allocare la memoria
si può provare a testare - fare una chiamata a ArrayCopy() con un grande volume di dati, preparando così la memoria del buffer per lo scambio, e poi fare un ciclo con ArrayCopy() con un volume di dati più piccolo per la copia e con la misurazione della velocità
Posso fare un brainstorming su un'implementazione veloce per tradurre un array di strutture (lunghezza multipla di sizeof(int)) da e verso un array int[]?
L'applicazione pratica è lo scambio veloce di dati attraverso le risorse. La mia variante è troppo universale, quindi rallenta.
Queste funzioni sono apparse in MT5
Non esistono e probabilmente non esisteranno in MT4. Quindi dobbiamo risolvere il problema con e senza queste funzioni (se sono utili).
Il risultato sarà utile a un gran numero di utenti del forum qui.
Ho scritto un modello molto semplice per il brainstorming con la mia soluzione a questo problema.
Risultato
Risultato
Qualcosa di considerevolmente più veloce della seconda opzione. Probabilmente non c'è modo di accelerarlo.
un'implementazione veloce per tradurre un array di strutture (lunghezza multipla di sizeof(int)) in e da un array int[]?
Qualcosa del genere
Qualcosa del genere.
Ben fatto! Entrerò nel codice, grazie.
Sembra che ArrayCopy sia davvero lento.
ZY Da un'esecuzione all'altra, ottengo risultati molto diversi. Per esempio, se cambio l'ordine dei Test, tutto viene quasi invertito. A quanto pare, ho bisogno di una misurazione della velocità più oggettiva.
ZZZ, ArrayCopy sembra essere un po' una seccatura.
Mi ricordo di aver misurato su qualche compito locale, dove dovevo copiare un piccolo numero di elementi. Fino a 16 elementi il ciclo for era molto più veloce di quello ArrayCopy, quando il numero di elementi era maggiore, quello ArrayCopy era più veloce. Naturalmente, la variante più veloce senza loop (come le mie funzioni nella pagina precedente)
Il modo più veloce è quello di farlo senza loop (come le mie funzioni nella pagina precedente).
Non capisco.
Non capisco.
Il mio punto è che for(int i=0; i<5; i++) dst[i]=src[i]; funziona più lentamente di dst[0]=src[0]; dst[1]=src[1]; dst[2]=src[2]; dst[3]=src[3]; dst[4]=src[4];
il che è abbastanza ovvio in vista delle operazioni aggiuntive relative al controllo del ciclo)
E CopyArray funziona molto più velocemente di entrambi, come ho controllato ora. Forse dipende dalla situazione, ovviamente.
Sì, questo funzionerà molto più velocemente (sostituito dove possibile da ArrayCopy, il resto è lo stesso):
Te l'ho detto, ho scritto la prima cosa che mi è venuta in mente senza nessun test))
E CopyArray, come ho controllato ora, funziona molto più velocemente di entrambe le opzioni, sembra. Forse dipende dalla situazione, naturalmente.
Se ArrayCopy() è fatta sul principio di Cish memmove(),
Penso che la velocità di ArrayCopy() dipenda dalla velocità di allocazione della memoria, se la memoria intermedia del buffer è pronta per la copia, ArrayCopy() sarà eseguita molto rapidamente, se la memoria non è allocata, si avvieranno richieste al sistema operativo per allocare la memoria
si può provare a testare - fare una chiamata a ArrayCopy() con un grande volume di dati, preparando così la memoria del buffer per lo scambio, e poi fare un ciclo con ArrayCopy() con un volume di dati più piccolo per la copia e con la misurazione della velocità