Question pour les experts en #define - page 4

 
Alexandr Andreev:

Le déploiement des fonctions normales va de soi.

Par exemple, pour (int i=0 ; i<ArraiSize(max) ; i++)

ici ArraiSize(max) ; sera développé et donnera quelque chose comme l'adresse de la taille du tableau donné (si nous regardons le tableau, il a sa taille dans une variable, et ici nous avons une substitution sur cette variable "adresse en mémoire") c'est-à-dire qu'il n'y a aucun sens à le changer en une variable, du tout

for (int i=0 ; i<ArraiSize(max) ; i++)

и

for (int i=0 ; i<size ; i++ )

Dans ce cas, ArraiSize(max) et size ont les mêmes timings pour déterminer la taille du tableau

déclaration incorrecte

testé : je l'ai essayé 1000 fois, 3 tableaux et 3 boucles imbriquées dans chaque tableau, 2 variantes : la 1ère et la 2ème

Le résultat est stable (testé 3 fois) :

2020.11.02 21:17:25.952 SpeedTst (EURUSD,H1) ArraySize : loops = 1000 seconds=114.5013

2020.11.02 21:17:40.713 SpeedTst (EURUSD,H1) cnt : boucles = 1000 secondes=99.7722

Je ne vois pas l'intérêt de discuter de la méthodologie des tests - très long et nécessaire.
 
Roman:

Dans cet exemple de boucle, je ne pense pas être d'accord sur les timings.
Au contraire, il est recommandé d'obtenir le résultat en variable de taille et de l'utiliser dans la condition.
Puisque la boucle à chaque itération pourArraiSize(max) se déroulera inutilement, ralentissant l'exécution de la boucle.

La fonction ArraiSize(max) développe et renvoie la cellule contenant l'enregistrement de la longueur du tableau ; l'adresse de la cellule où est stockée la longueur du tableau est renvoyée

et ce qui est une variable quelconque, dans ce cas la taille - est l'adressede la cellule où la longueur du tableau est stockée

Nous obtenons donc la même chose à la sortie et même si nous changeons la taille du tableau au cours de la boucle, l'adresse par cellule ne changera ni dans le premier ni dans le second cas.

Puisque la valeur mas est toujours statique (il ne s'agit pas d'une référence), il ne peut tout simplement pas y avoir d'autre logique)).

La fonction ArraiSize(max) elle-même indique qu'une section de mémoire dans le tableaumax doit être utilisée pour la longueur du tableau ; ceci est effectué à l'étape de la compilation - déploiement de la fonction.

 
Igor Makanu:

déclaration incorrecte

testé : comptage 1000 fois, 3 tableaux et 3 boucles imbriquées de force brute sur chaque tableau, 2 variantes : 1ère et 2ème

Le résultat est stable (testé 3 fois) :

2020.11.02 21:17:25.952 SpeedTst (EURUSD,H1) ArraySize : loops = 1000 seconds=114.5013

2020.11.02 21:17:40.713 SpeedTst (EURUSD,H1) cnt : boucles = 1000 secondes=99.7722

Je ne vois pas l'intérêt de discuter de la méthodologie des tests - très long et nécessaire.

puis quelques problèmes avec la construction....

 
Alexandr Andreev:

alors il y a quelques problèmes avec l'assemblage....

Il est clair que le résultat est le même.
Mais l'accès à cette section de la mémoire sera différent, c'était le but.
L'accès à une variable est plus rapide que celui à une fonction, puisque la variable contient déjà la valeur.
Et une fonction doit encore récupérer cette valeur et la renvoyer, c'est-à-dire faire référence à une cellule mémoire, une instruction inutile.

L'exemple d'Igor ne fait que confirmer ce que je disais.

 
Alexandr Andreev:

puis quelques problèmes avec l'assemblée....

menti

ArraySize() est appelé à chaque itération

même si vous ne vérifiez pas la taille du tableau à chaque fois, vous avez toujours un appel de procédure et au moins une vérification de la variable stockant la taille du tableau.

voici le test sur lequel j'écris, nous redimensionnons le tableau dans la boucle, la boucle est interrompue comme il se doit, c'est-à-dire qu'à chaque itération de la boucle, la taille du tableau est déterminée après l'exécution du corps de la boucle :

void OnStart()
{
   int arr[];
   int sz = ArrayResize(arr, 100000);
   int cnt = 0;
   for(int i = 0; i < ArraySize(arr); i++)
   {
      ArrayResize(arr, sz--);
      cnt++;
   }
   printf("cnt = %i", cnt);   //cnt = 50001
}
 
Igor Makanu:

menti

ArraySize() est appelé à chaque itération

même si la taille du tableau n'est pas vérifiée à chaque fois, la procédure est toujours appelée et au moins la variable stockant la taille du tableau est vérifiée.

Voici le test sur lequel je suis en train d'écrire : nous redimensionnons le tableau dans la boucle, la boucle se termine comme prévu, c'est-à-dire qu'à chaque itération de la boucle, la taille du tableau est définie après l'exécution du corps de la boucle :

Donnez-moi le code complet de votre test.

Romain:

Il est clair que nous obtenons la même chose en sortie.
Mais ce fragment de mémoire sera récupéré différemment, c'est ce que je veux dire.

L'exemple d'Igor ne fait que confirmer ce que je disais.

Et vous avez vous-même effectué le test, je suis à 110000000000000000000 quelque chose comme ça n'arrive pas.

Plus précisément, je ne l'ai pas du tout dans aucun des tests, même àLONG_MAX répétitions
 
Alexandr Andreev:

La fonction ArraiSize(max) est étendue, elle prend une cellule avec la longueur enregistrée du tableau et la retourne, l'adresse de la cellule où la longueur du tableau est enregistrée

et ce qui est une variable quelconque, dans ce cas la taille - est l'adressede la cellule où la longueur du tableau est stockée

Nous obtenons donc la même chose à la sortie et même si nous changeons la taille du tableau au cours de la boucle, l'adresse par cellule ne changera ni dans le premier ni dans le second cas.

Puisque la valeur mas est toujours statique (il ne s'agit pas d'une référence), il ne peut tout simplement pas y avoir d'autre logique)).

La fonction ArraiSize(max) elle-même indique que nous devons utiliser une zone de mémoire dans le tableaumax responsable de la longueur du tableau et ceci est exécuté à l'étape de la compilation - déploiement de la fonction

Cet avis semble être prématuré. Ce qui se passe exactement derrière la fonction ArraiSize est inconnu, n'est-ce pas ? C'est une boîte noire dans MQL. Il est tout à fait possible que for (int i=0 ; i<ArraiSize(max) ; i++) conduise à l'exécution de plusieurs instructions. Par exemple, une fonction peut vérifier les paramètres d'entrée. Sauvegarder - pousser les données hors de la pile. Sauver les registres. Restaurer les registres. Appel de fonction - appel, puis retour. Ce que je veux dire, c'est que beaucoup de choses peuvent se passer en arrière-plan et que nous ne pouvons pas les voir. C'est pourquoi il est préférable d'utiliser for (int i=0 ; i<size ; i++) et de ne pas compter sur le compilateur pour faire ce que nous attendons de lui.

 
Alexandr Andreev:

Vous avez fait le test vous-même, je ne l'ai pas à 110000000000000000000.


Il a été testé il y a longtemps, c'est pourquoi je n'utilise les variables que dans les boucles.

 
Roman:

Cela a été testé il y a longtemps, donc je n'utilise les variables que dans les boucles.

Montrez-moi un test avec le code

 
Alexandr Andreev:

Montrez-moi le test de code

Quel test ? ))
Vous avez vous-même montré les deux variantes de la condition de la boucle.
Igor a également donné le code ci-dessus.
Il suffit de mesurer l'exécution de la boucle avec la variable size et avec ArraySize( ) dans la condition de la boucle.