Puis-je réfléchir à une implémentation rapide de la traduction d'un tableau de structures (longueur multiple de sizeof(int)) vers et depuis un tableau int[]?
L'application pratique est l'échange rapide de données via les ressources. Ma variante est trop universelle, ce qui la ralentit.
Ces fonctions sont apparues dans MT5
StructToCharArray
CharArrayToStruct
Ils n'existent pas dans MT4 et n'existeront probablement pas. Par conséquent, nous devons résoudre le problème avec et sans ces fonctions (si elles sont utiles).
Le résultat sera utile à un grand nombre d'utilisateurs du forum ici.
J'ai écrit un modèle très simple pour le brainstorming avec ma solution à ce problème.
// Решения задачи: 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 D'une course à l'autre, j'obtiens des résultats très différents. Par exemple, si je change l'ordre des tests, tout s'inverse presque. Apparemment, j'ai besoin d'une mesure de vitesse plus objective.
Sans beaucoup de réflexion et de débogage, j'ai écrit la première chose qui m'est venue à l'esprit, donc il peut y avoir beaucoup de problèmes. Je n'ai jamais été confronté moi-même à une telle tâche (bien que j'aie beaucoup travaillé avec des syndicats).
Je me souviens avoir mesuré une tâche locale, où je devais copier un petit nombre d'éléments. Jusqu'à 16 éléments, la boucle for était beaucoup plus rapide que la boucle ArrayCopy. Lorsque le nombre d'éléments était plus important, la boucle ArrayCopy était plus rapide. Bien sûr, la variante la plus rapide sans aucune boucle (comme mes fonctions à la page précédente)
Ce que je veux dire, c'est que for(int i=0 ; i<5 ; i++) dst[i]=src[i] ; fonctionne plus lentement que dst[0]=src[0];dst[1]=src[1];dst[2]=src[2];dst[3]=src[3];dst[4]=src[4] ;
ce qui est assez évident au vu des opérations supplémentaires liées au contrôle de la boucle)
Et CopyArray fonctionne beaucoup plus rapidement que les deux, comme je l'ai vérifié maintenant. Cela dépend peut-être de la situation, bien sûr.
Et CopyArray, comme je l'ai vérifié maintenant, fonctionne beaucoup plus rapidement que les deux options, il me semble. Cela dépend peut-être de la situation, bien sûr.
Si ArrayCopy() est fait sur le principe de Cish memmove(),
Je pense que la vitesse d'ArrayCopy() dépend de la vitesse d'allocation de la mémoire, si la mémoire tampon intermédiaire est prête à être copiée, ArrayCopy() sera exécuté très rapidement, si la mémoire n'est pas allouée, vous commencerez à demander au système d'exploitation d'allouer la mémoire
vous pouvez essayer de tester - faire un appel à ArrayCopy() avec un grand volume de données, préparant ainsi la mémoire tampon pour l'échange, et ensuite faire une boucle avec ArrayCopy() avec un plus petit volume de données pour la copie et avec la mesure de vitesse
Si vous n'avez pas de compte, veuillez vous inscrire
Autorisez l'utilisation de cookies pour vous connecter au site Web MQL5.com.
Veuillez activer les paramètres nécessaires dans votre navigateur, sinon vous ne pourrez pas vous connecter.
Vous êtes connecté. L'authentification à deux facteurs a été désactivée. Configurez-la à nouveau et scannez un nouveau code QR, ou continuez avec l'authentification à deux facteurs désactivée.
Puis-je réfléchir à une implémentation rapide de la traduction d'un tableau de structures (longueur multiple de sizeof(int)) vers et depuis un tableau int[]?
L'application pratique est l'échange rapide de données via les ressources. Ma variante est trop universelle, ce qui la ralentit.
Ces fonctions sont apparues dans MT5
Ils n'existent pas dans MT4 et n'existeront probablement pas. Par conséquent, nous devons résoudre le problème avec et sans ces fonctions (si elles sont utiles).
Le résultat sera utile à un grand nombre d'utilisateurs du forum ici.
J'ai écrit un modèle très simple pour le brainstorming avec ma solution à ce problème.
Résultat
Résultat
Quelque chose de beaucoup plus rapide que la deuxième option. Il n'y a probablement aucun moyen d'accélérer le processus.
uneimplémentation rapide de la traduction d'un tableau de structures (longueur multiple de sizeof(int)) vers et depuis un tableau int[]?
Quelque chose comme ça
Quelque chose comme ça.
Bien joué ! Je vais m'occuper du code, merci.
On dirait que ArrayCopy est vraiment lent.
ZY D'une course à l'autre, j'obtiens des résultats très différents. Par exemple, si je change l'ordre des tests, tout s'inverse presque. Apparemment, j'ai besoin d'une mesure de vitesse plus objective.
ZZZ, ArrayCopy semble être un peu un frein.
Je me souviens avoir mesuré une tâche locale, où je devais copier un petit nombre d'éléments. Jusqu'à 16 éléments, la boucle for était beaucoup plus rapide que la boucle ArrayCopy. Lorsque le nombre d'éléments était plus important, la boucle ArrayCopy était plus rapide. Bien sûr, la variante la plus rapide sans aucune boucle (comme mes fonctions à la page précédente)
Le moyen le plus rapide est de le faire sans aucune boucle (comme mes fonctions de la page précédente).
Je ne comprends pas.
Je ne comprends pas.
Ce que je veux dire, c'est que for(int i=0 ; i<5 ; i++) dst[i]=src[i] ; fonctionne plus lentement que dst[0]=src[0];dst[1]=src[1];dst[2]=src[2];dst[3]=src[3];dst[4]=src[4] ;
ce qui est assez évident au vu des opérations supplémentaires liées au contrôle de la boucle)
Et CopyArray fonctionne beaucoup plus rapidement que les deux, comme je l'ai vérifié maintenant. Cela dépend peut-être de la situation, bien sûr.
Oui, cela fonctionnera beaucoup plus rapidement (remplacé dans la mesure du possible par ArrayCopy, le reste est identique) :
Je vous l'ai dit, j'ai écrit la première chose qui m'est venue à l'esprit sans faire de tests ;))
Et CopyArray, comme je l'ai vérifié maintenant, fonctionne beaucoup plus rapidement que les deux options, il me semble. Cela dépend peut-être de la situation, bien sûr.
Si ArrayCopy() est fait sur le principe de Cish memmove(),
Je pense que la vitesse d'ArrayCopy() dépend de la vitesse d'allocation de la mémoire, si la mémoire tampon intermédiaire est prête à être copiée, ArrayCopy() sera exécuté très rapidement, si la mémoire n'est pas allouée, vous commencerez à demander au système d'exploitation d'allouer la mémoire
vous pouvez essayer de tester - faire un appel à ArrayCopy() avec un grand volume de données, préparant ainsi la mémoire tampon pour l'échange, et ensuite faire une boucle avec ArrayCopy() avec un plus petit volume de données pour la copie et avec la mesure de vitesse