Implémentations alternatives de fonctions/approches standard - page 10

 
pavlick_:
)). Cela peut avoir une place seulement dans les métiers personnels avec une connaissance exacte de la gamme de valeurs, mais pas dans les bibliothèques std. Les fonctions intégrées ne sont pas écrites par des imbéciles, ne pensez pas que vous êtes le plus intelligent. Voici un ami qui écrit également un comportement indéfini et non spécifié et qui s'étonne ensuite que cela ne fonctionne pas de cette façon https://www.linux.org.ru/forum/development/14422428#comments. Toutes ces économies de plusieurs nanosecondes ne seront même pas visibles dans l'algorithme réel (pas dans la boucle nue).

Ce n'est que maintenant que j'ai compris ce que tu disais.
Je retire que vous n'êtes pas dans le coup. Je m'excuse.
Oui, vous pouvez utiliser cette variante, à condition que le nombre double soit compris entre -9007199254740992 et 9007199254740992 (2 à la puissance 53 (nombre de bits dans la mantisse)).

 
Renat Fatkhullin:
Pensez à ce que vous obtiendrez en dehors de l'intervalle des nombres entiers.

Que pensez-vous de ça ?

double Ceil (double x) { return double((x>9007199254740992 || x<-9007199254740992 )?x:(x-(long)x>0)?(long)x+1:(long)x);}
double Round(double x) { return double((x>9007199254740992 || x<-9007199254740992 )?x:(x>0)?(long)(x+0.5):(long)(x-0.5));}
double Floor(double x) { return double((x>9007199254740992 || x<-9007199254740992 )?x:(x>0)?(long)x:((long)x-x>0)?(long)x-1:(long)x);}

résultat :

2018.08.26 10:49:23.552 TestRound (Crypto.ALT,M10)      Время цикла без округления = 1.317 наносекунд, сумма = 115583114403605978808320.00000000
2018.08.26 10:49:23.556 TestRound (Crypto.ALT,M10)      Время выполнения функции ceil =  2.129 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 10:49:23.557 TestRound (Crypto.ALT,M10)      Время выполнения функции Ceil =  0.100 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 10:49:23.560 TestRound (Crypto.ALT,M10)      Время выполнения функции floor = 1.299 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 10:49:23.561 TestRound (Crypto.ALT,M10)      Время выполнения функции Floor = 0.120 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 10:49:23.564 TestRound (Crypto.ALT,M10)      Время выполнения функции round = 1.787 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 10:49:23.566 TestRound (Crypto.ALT,M10)      Время выполнения функции Round = 0.106 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 10:49:23.566 TestRound (Crypto.ALT,M10)      Идет бесконечный поиск расхождения по случайным числам double ... Прервите скрипт, когда надоест ждать

le test semble montrer une identité complète.

Cependant, la vitesse de la solution alternative dans ce cas, où il y a une vérification de l'intervalle, est plus élevée d'environ 2 fois (au lieu de 3-8), mais c'est si le nombre double est dans l'intervalle de-9007199254740992 à 9007199254740992. Mais elle est beaucoup plus élevée lorsqu'elle se situe en dehors de cette fourchette.

Dossiers :
TestRound.mq5  9 kb
 
Nikolai Semko:


le test semble montrer une identité complète.

Cependant, cette variante ne prend pas en compte le débordement de la variable d'entréede type double, lorsqu'elle prend les valeurs nan, snan.

S'il faut en tenir compte, vous pouvez ajouter un contrôle supplémentaire, mais cette variante fonctionnera quand même plus rapidement que la fonction originale

double Ceil (double x) { return double((!MathIsValidNumber(x) || x>9007199254740992 || x<-9007199254740992 )?x:(x-(long)x>0)?(long)x+1:(long)x);}
double Round(double x) { return double((!MathIsValidNumber(x) || x>9007199254740992 || x<-9007199254740992 )?x:(x>0)?(long)(x+0.5):(long)(x-0.5));}
double Floor(double x) { return double((!MathIsValidNumber(x) || x>9007199254740992 || x<-9007199254740992 )?x:(x>0)?(long)x:((long)x-x>0)?(long)x-1:(long)x);}
 
Nikolai Semko:

Rédiger un EA pour un testeur/optimisateur. C'est là que la rapidité de la pratique est importante.

 
fxsaber:

Rédiger un EA pour un testeur/optimisateur. C'est là que la vitesse est importante dans la pratique.

Comme beaucoup de gens le savent, je fais aussi des graphiques lisses. C'est pour lisser les graphiques et travailler avec chaque pixel que les fonctions d'arrondi sont activement utilisées.

Auparavant, je ne pouvais même pas imaginer que la fonction d'arrondi soit plus lente que l'extraction de la racine carrée du double.
C'est pour cette raison que j'ai pris l'habitude d'étouffer ces nanosecondes. Car ces nanosecondes sur le graphique lissé peuvent se transformer en millisecondes sur chaque image, et une image peut changer toutes les 33 millisecondes.

 
Nikolai Semko:

Comme beaucoup de gens le savent, je m'occupe également des graphiques anti-alias. C'est pour les graphiques anti-alias et le travail avec chaque pixel que les fonctions d'arrondi sont activement utilisées.
C'est pour cette raison que je me suis engagé à lisser ces nanosecondes. Car ces nanosecondes sur les graphiques lissés peuvent se transformer en millisecondes sur chaque image, et une image peut changer toutes les 33 millisecondes.

Bien sûr, c'est important pour les graphiques. C'est pourquoi des optimisations algorithmiques pour presque toutes les tâches courantes y existent depuis très longtemps.

 
fxsaber:

Bien sûr, c'est important pour les graphiques. C'est pourquoi des optimisations algorithmiques pour presque toutes les tâches courantes y existent depuis très longtemps.

Vous vous trompez. Le champ n'est toujours pas labouré, et ce qui est labouré est fermé. Et dans MQL d'autant plus. La classe CCanvas est très loin de l'optimalité et il n'y a presque pas d'antialiasing et ce qu'il y a d'antialiasing est insatisfaisant.

 

Pourquoi n'utilisez-vous pas LONG_MAX/MIN? Ce serait plus joli d'une certaine façon. C'est joli, je trouve. J'ai effectué vos tests avec gcc (avec une modification min, bien sûr, très vieux compilateur 5.4.0, ce que j'avais sous la main) :

1. Compilation avec -O3.

Время цикла без округления = 0.001099185 секунд, сумма = 1.15583114 e+23
Время выполнения функции ceil =  0.004310106 секунд, сумма = 1.15583114 e+23
Время выполнения функции Ceil =  0.001912712 секунд, сумма = 1.15583114 e+23
Время выполнения функции floor =  0.005283493 секунд, сумма = 1.15583114 e+23
Время выполнения функции Floor =  0.002031304 секунд, сумма = 1.15583114 e+23
Время выполнения функции round =  0.005308409 секунд, сумма = 1.15583114 e+23
Время выполнения функции Round =  0.002344382 секунд, сумма = 1.15583114 e+23

2. Compilation avec -Ofast

Время цикла без округления = 0.000552652 секунд, сумма = 1.15583114 e+23
Время выполнения функции ceil =  0.001720999 секунд, сумма = 1.15583114 e+23
Время выполнения функции Ceil =  0.00189282 секунд, сумма = 1.15583114 e+23
Время выполнения функции floor =  0.001430063 секунд, сумма = 1.15583114 e+23
Время выполнения функции Floor =  0.001979336 секунд, сумма = 1.15583114 e+23
Время выполнения функции round =  0.001698521 секунд, сумма = 1.15583114 e+23
Время выполнения функции Round =  0.001944874 секунд, сумма = 1.15583114 e+23

Votre code a un problème avec le calcul du temps - la sortie est en millisecondes (pas en nano), et je ne comprends toujours pas pourquoi vous avez besoin de moins t0.

Print("Время выполнения функции ceil =  "+DoubleToString((double)(GetMicrosecondCount()-t-t0)/1000,3)+" наносекунд, Контрольная сумма = "+string(s));
 
Nikolai Semko:

Faux. Il y a encore un champ non labouré, et ce qui est labouré est fermé.

Je parlais de l'expérience du monde. Regardez les algorithmes sur les forums thématiques où ils font des démonstrations de graphiques. Les gens partagent leurs algorithmes rapides.

 
fxsaber:

Je parlais de l'expérience du monde. Recherchez les algorithmes sur les forums thématiques où des démonstrations de graphes sont réalisées. Les gens partagent des algorithmes rapides.

Pouvez-vous m'envoyer le lien ?