Kann ich Brainstorming auf eine schnelle Implementierung der Übersetzung eines Arrays von Strukturen (Länge Vielfache von sizeof(int)) zu und von einem int[] Array?
Praktische Anwendung ist der schnelle Datenaustausch über Ressourcen. Meine Variante ist zu universell, so dass sie sich verlangsamt.
Diese Funktionen wurden in MT5 eingeführt
StructToCharArray
CharArrayToStruct
Diese gibt es in MT4 nicht und wird es wahrscheinlich auch nicht geben. Wir müssen also das Problem mit und ohne diese Funktionen lösen (falls sie nützlich sind).
Das Ergebnis wird für eine große Zahl von Forumsnutzern hier nützlich sein.
Ich habe eine sehr einfache Vorlage für ein Brainstorming mit meiner Lösung für dieses Problem geschrieben.
// Решения задачи: 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));
}
/***********************************************/
Gut gemacht! Ich werde mich mit dem Code befassen, danke.
Klingt so, als ob ArrayCopy ein echter Langweiler ist.
ZY Von Lauf zu Lauf erhalte ich sehr unterschiedliche Ergebnisse. Wenn ich zum Beispiel die Reihenfolge der Tests ändere, wird fast alles umgedreht. Offensichtlich ist eine objektivere Geschwindigkeitsmessung erforderlich.
Ohne viel nachzudenken und zu debuggen, habe ich das erste geschrieben, was mir in den Sinn kam, daher kann es eine Menge Fehler geben. Ich bin selbst noch nie mit einer solchen Aufgabe konfrontiert worden (obwohl ich viel mit Gewerkschaften gearbeitet habe).
ZZZ, ArrayCopy scheint ein bisschen lästig zu sein.
Ich erinnere mich, dass ich an einer lokalen Aufgabe gemessen habe, bei der ich eine kleine Anzahl von Elementen kopieren musste. Bis zu 16 Elementen war die for-Schleife viel schneller als die ArrayCopy-Schleife, wenn die Anzahl der Elemente größer war, war die ArrayCopy-Schleife schneller. Natürlich ist die schnellste Variante ganz ohne Schleifen (wie meine Funktionen auf der vorherigen Seite)
Mein Punkt ist, dass for(int i=0; i<5; i++) dst[i]=src[i]; langsamer arbeitet als dst[0]=src[0];dst[1]=src[1];dst[2]=src[2];dst[3]=src[3];dst[4]=src[4];
was in Anbetracht der zusätzlichen Operationen im Zusammenhang mit der Schleifensteuerung ziemlich offensichtlich ist)
Und CopyArray funktioniert viel schneller als beide, wie ich es jetzt überprüft habe. Vielleicht hängt es natürlich von der Situation ab.
Und CopyArray, wie ich es jetzt überprüft habe, funktioniert viel schneller als beide Optionen, so scheint es. Das hängt natürlich von der jeweiligen Situation ab.
Wenn ArrayCopy() nach dem Prinzip von Cish memmove() durchgeführt wird,
Ich denke, die Geschwindigkeit von ArrayCopy() hängt von der Geschwindigkeit der Speicherzuweisung ab, wenn der Zwischenpufferspeicher zum Kopieren bereit ist, wird ArrayCopy() sehr schnell ausgeführt, wenn der Speicher nicht zugewiesen ist, werden Sie Anfragen an das Betriebssystem starten, um Speicher zuzuweisen
Sie können versuchen zu testen - machen Sie einen Aufruf von ArrayCopy() mit einer großen Datenmenge, wodurch der Pufferspeicher für den Austausch vorbereitet wird, und machen Sie dann eine Schleife mit ArrayCopy() mit einer kleineren Datenmenge zum Kopieren und mit dem Geschwindigkeitsmesser
Kann ich Brainstorming auf eine schnelle Implementierung der Übersetzung eines Arrays von Strukturen (Länge Vielfache von sizeof(int)) zu und von einem int[] Array?
Praktische Anwendung ist der schnelle Datenaustausch über Ressourcen. Meine Variante ist zu universell, so dass sie sich verlangsamt.
Diese Funktionen wurden in MT5 eingeführt
Diese gibt es in MT4 nicht und wird es wahrscheinlich auch nicht geben. Wir müssen also das Problem mit und ohne diese Funktionen lösen (falls sie nützlich sind).
Das Ergebnis wird für eine große Zahl von Forumsnutzern hier nützlich sein.
Ich habe eine sehr einfache Vorlage für ein Brainstorming mit meiner Lösung für dieses Problem geschrieben.
Ergebnis
Ergebnis
Etwas, das wesentlich schneller ist als die zweite Option. Es gibt wahrscheinlich keine Möglichkeit, dies zu beschleunigen.
eineschnelle Implementierung der Umwandlung eines Arrays von Strukturen (Länge ein Vielfaches von sizeof(int)) in und aus einem int[]-Array?
Etwa so
Etwa so.
Gut gemacht! Ich werde mich mit dem Code befassen, danke.
Klingt so, als ob ArrayCopy ein echter Langweiler ist.
ZY Von Lauf zu Lauf erhalte ich sehr unterschiedliche Ergebnisse. Wenn ich zum Beispiel die Reihenfolge der Tests ändere, wird fast alles umgedreht. Offensichtlich ist eine objektivere Geschwindigkeitsmessung erforderlich.
ZZZ, ArrayCopy scheint ein bisschen lästig zu sein.
Ich erinnere mich, dass ich an einer lokalen Aufgabe gemessen habe, bei der ich eine kleine Anzahl von Elementen kopieren musste. Bis zu 16 Elementen war die for-Schleife viel schneller als die ArrayCopy-Schleife, wenn die Anzahl der Elemente größer war, war die ArrayCopy-Schleife schneller. Natürlich ist die schnellste Variante ganz ohne Schleifen (wie meine Funktionen auf der vorherigen Seite)
Am schnellsten geht es, wenn Sie ganz ohne Schleifen auskommen (wie meine Funktionen auf der vorherigen Seite).
Das verstehe ich nicht.
Das verstehe ich nicht.
Mein Punkt ist, dass for(int i=0; i<5; i++) dst[i]=src[i]; langsamer arbeitet als dst[0]=src[0];dst[1]=src[1];dst[2]=src[2];dst[3]=src[3];dst[4]=src[4];
was in Anbetracht der zusätzlichen Operationen im Zusammenhang mit der Schleifensteuerung ziemlich offensichtlich ist)
Und CopyArray funktioniert viel schneller als beide, wie ich es jetzt überprüft habe. Vielleicht hängt es natürlich von der Situation ab.
Ja, dies wird viel schneller funktionieren (wo möglich ersetzt durch ArrayCopy, der Rest ist derselbe):
Wie gesagt, ich habe das Erste geschrieben, was mir in den Sinn kam, ohne Tests))
Und CopyArray, wie ich es jetzt überprüft habe, funktioniert viel schneller als beide Optionen, so scheint es. Das hängt natürlich von der jeweiligen Situation ab.
Wenn ArrayCopy() nach dem Prinzip von Cish memmove() durchgeführt wird,
Ich denke, die Geschwindigkeit von ArrayCopy() hängt von der Geschwindigkeit der Speicherzuweisung ab, wenn der Zwischenpufferspeicher zum Kopieren bereit ist, wird ArrayCopy() sehr schnell ausgeführt, wenn der Speicher nicht zugewiesen ist, werden Sie Anfragen an das Betriebssystem starten, um Speicher zuzuweisen
Sie können versuchen zu testen - machen Sie einen Aufruf von ArrayCopy() mit einer großen Datenmenge, wodurch der Pufferspeicher für den Austausch vorbereitet wird, und machen Sie dann eine Schleife mit ArrayCopy() mit einer kleineren Datenmenge zum Kopieren und mit dem Geschwindigkeitsmesser