A SUPPRIMER

MadM@tt Messages postés 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 - 1 mai 2005 à 19:47
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 - 3 mai 2005 à 08:53
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/31126-a-supprimer

us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
3 mai 2005 à 08:53
Une précision :

Pour en finir avec les temps des boucles, j'ai effectué 4 tests, consistant à tester la rapidité d'une boucle FOR TO NEXT en fonction de la façon dont on paramètre... (soit directement avec l'expression numérique, soit en passant par une variable)...

Ce qui resort, c'est que le plus important pour le gain de temps, c'est de mettre la borne supérieure dans une variable (gain important)... la borne inférieure est préférable en calcul (mais le gain est trés faible, par rapport à une variable)... Le pas 'step' ralentir quant il est dans une variable (perte assez faible, tout de même)...

Exemple utilisé :

Function test1()
'6,48

temps = Timer

For t = 1 To 1000000
For q = 2 * 3 + 1 / Cos(t) To Exp(10) + 3 * 98.54 Step t / 2 + 2 * 5 - 10
S = S + 1
Next q, t

MsgBox Timer - temps & " :" & S

End Function




Function test2()
'5,05

temps = Timer

A = Exp(10) + 3 * 98.54
For t = 1 To 1000000
For q = 2 * 3 + 1 / Cos(t) To A Step t / 2 + 2 * 5 - 10
S = S + 1
Next q, t

MsgBox Timer - temps & " :" & S

End Function





Function test3()
'5,09

temps = Timer

A = Exp(10) + 3 * 98.54
For t = 1 To 1000000
A2 = 2 * 3 + 1 / Cos(t)
For q = A2 To A Step t / 2 + 2 * 5 - 10
S = S + 1
Next q, t

MsgBox Timer - temps & " :" & S

End Function





Function test4()
'5,28

temps = Timer

A = Exp(10) + 3 * 98.54
For t = 1 To 1000000
A2 = 2 * 3 + 1 / Cos(t)
A3 = t / 2 + 2 * 5 - 10
For q = A2 To A Step A3
S = S + 1
Next q, t

MsgBox Timer - temps & " :" & S

End Function



A+
Us.
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
2 mai 2005 à 20:43
Aprés plusieurs essais, j'ai trouvé que :

A1 : accèlère (un poil) l'algorithme de nos versions.... et
saut1 : Pénalises chaque version...

Donc maintenant, avec A1 sur ma version j'arrive en gros à 10,05... et des poussières....

En remplçant saut1 par son expression, j'accèlére ta version, qui maintenat arrive en tête avec 9,66...

Pourquoi saut1 fait ralentir et A1 accèlère... est-ce dû au fait que saut1 est un calcul avec une puissance entière (^2) et donc donne un nb entier... ce qui est différent de A1 (calcul d'une racine carré)... Bref, j'en connais pas la réponse... de plus la mesure est assez faible... on arrive un peu aux limites....

Mais je vais garder tout de même la version qui semble la plus rapide au finale... (donc ta version avec expression math)... du moins il serait intéressant de confirmer que les résultats que j'obtiens, soit dans le même sens pour tout monde...


Amicalement,
Us.
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
2 mai 2005 à 20:20
Bon... Comme tu sembles sur de ce point, je regarde ce que cela donne au niveau du temps...
Mindiell Messages postés 558 Date d'inscription jeudi 25 juillet 2002 Statut Membre Dernière intervention 5 septembre 2007 1
2 mai 2005 à 20:04
A1 est utilisé à chaque boucle, étant donné qu'il reteste la valeur de "liste"...

Bizarre, en effet, mais j'ai p'tet laissé une erreur se glisser... Je vérifierais ^^
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
2 mai 2005 à 19:45
Ta première remarque suivante n'est pas dénuée de bon sens :

"- Tu ne vérifies plus que A est > 3... et avec ce genre de calculs "(A - 3) / 2" c'est embetant, non ? "

mais... ici, cela ne pose pas de problème. Pourquoi ? Tout simplement parce si on déclare le tableau avec un indice compris entre -1 (non compris) et 0, visual basic l'interprète comme zéro... Par contre, une valeur négative (-1 par exemple) , il y a une erreur...

En précis, si on regarde ce qu'il se passe pour :

A<=1 alors il est traité par : "If A <= 1 Then NbPi = 0: Exit Function" >>> donc pas de souci... (et répond au problème du test de A négatif...)

A=2 alors (A-3)/2 donne -0,5... La déclaration dans le tableau est interprété en Zéro soit : "ReDim nb(0)"

A=3 alors le p'tit calcul donne Zéro... plus de souci...

En conclusion, la fonction fonctionne donc correctement même pour les valeurs inférieures à 3... Ce que j'ai pu vérifier... aucune erreur se produit, et j'ai aussi vérifié l'exactitude des résultats renvoyés...


LA seconde remarque :
---------------------------
"- Tu utilises souvent ce nombre : "(A - 3) / 2", calcule le une fois et c'est tout. Sans ca, il recalcule a chaque boucle, idem pour : "((saut ^ 2) - 3) / 2" et "((A ^ 0.5) - 3) / 2" . Il y a juste "((saut ^ 2) - 3) / 2" à recalculer avant la deuxième boucle, donc dans la première."


JE retiens la bonne remarque de mettre (A-3)/2 dans une variable une fois pour toute... C'est un de mes défaut, d'ailleurs...



La troisième remarque :
-----------------------------
* A = Int(A) : signifie que je garde que la partie entière (au cas où il serait avec une virgule) mais cela ne change pas son type... "A" reste en Double... donc rien d'étrange (confusion avec Integer ?)...

Ensuite la déclaration du tableau ne prend pas le type de l'indice, mais Byte avec As Byte... Cela permet d'économiser la mémoire et accélère les opérations, puisque j'ai juste bessoin d'écrire "1"... A la limite, s'il existait une déclaration d'un tableau contenant un seul bit, cela suffit dans mon cas... (mais ce type hélas, n'existe pas, donc je prends le plus petit possible, le type boolean vaut aussi 8 bits)... J'ai fait un petit essai en déclarant le tableau "nb()" en Double, l'algo met +18% de temps en plus...

Enfin, le "Else".... vraiment utile ? et bien, je crois qu'il n'est pas vraiment super utile.... MAIS.... en testant ta proposition, avec la mienne... ET bien, aussi étrange que cela puisse paraître, j'ai un trés léger avantage... EN fait pour être tout à fait honnête, les résultats ne sembles pas s'écarter de beaucoup, aux erreurs de variations prés... (voir les résultats stat ci-aprés)

Mais, bon... ma programmation semble moins "propre"...

Pour finir, A1 et saut1 ne sont utilisés qu'une seule fois, donc il me semble préférable de laisser le calcul dans la boucle... Le calcul dans la boucle n'étant fait qu'une fois...


TEST :
-----

J'ai essayé les 2 versions, (sur mon pentium II, tintin tin !) (avec la modif A2 pour mon algo)

avec :
* temps = Timer >>>au début et...
* MsgBox "Fonction 1 : " & Timer - temps >>>à la fin...

Pour la borne A=1000000 (1 million) et j'ai obtenus les résultats suivants :

Ta version : 1,054688 - 1,1015163 - 1,039063 - 1,039063 - 1,054688

Ma version : 0,984075 - 0,9921875 - 0,9921875 - 0,9921875 - 0,984375

=

Pour la borne A=10000000 (10 million) et j'ai obtenus les résultats suivants :

Ta version : 11,25781 - 11,21094 - 11,20313 - 11,21094 - 11,21094

Ma version : 10,875 - 10,42969 - 10,44531 - 10,38281 - 10,375

Ouf... Voilà... Ces résultats sont paradoxales puisque ta version semble plus compact... mais bon... je n'ai point triché... à confirmer, si l'emploi du temps le permet...

euh... enfin... dernier détail pour 10 millions, il y a 664579 nombres premiers ! ... c'est tout de même le but de la fonction...


Amicalement,
Us.
Mindiell Messages postés 558 Date d'inscription jeudi 25 juillet 2002 Statut Membre Dernière intervention 5 septembre 2007 1
2 mai 2005 à 13:41
Bon, vite fait sans trop réfléchir :

- Tu ne vérifies plus que A est > 3... et avec ce genre de calculs "(A - 3) / 2" c'est embetant, non ? ^^

- Tu utilises souvent ce nombre : "(A - 3) / 2", calcule le une fois et c'est tout. Sans ca, il recalcule a chaque boucle, idem pour : "((saut ^ 2) - 3) / 2" et "((A ^ 0.5) - 3) / 2"
Il y a juste "((saut ^ 2) - 3) / 2" à recalculer avant la deuxième boucle, donc dans la première.

- Tu utilises ca :
* Function NbPi(A As Double)
* A = Int(A)
* ReDim nb((A - 3) / 2) As Byte '1 octet par nombre
Donc A passe d'un double à un entier, et le tableau ne contient que des byte.... Bizarre, non ?

- Ton A n'est pas positif ! :
* 'Traitement A en entier positif
* A = Int(A)
Il faut A = Abs(A)...

- Enfin, ton else est-il vraiment utile ?

Voilà ce que je proposerais en gros :
"
A1 = ((A ^ 0.5) - 3) / 2
A2 = (A - 3) / 2
For liste = 0 To A1
If nb(liste) = 0 Then
saut = (2 * liste) + 3
saut1 = ((saut ^ 2) - 3) / 2
For t = saut1 To A2 Step saut
nb(t) = 1
Next t
End If
Next liste

For t = 0 To A2 Step 1
If nb(t) = 0 Then
B = B + 1
End If
Next t
"

Pas le temps d'essayer, dis moi si c'est plus efficace :)

PS: j'ai fait ca très vite, regarde donc plus mes remarques que mes corrections qui contiennent peut-être des erreurs...
sim2005 Messages postés 1 Date d'inscription dimanche 27 février 2005 Statut Membre Dernière intervention 2 mai 2005
2 mai 2005 à 13:27
tres favorables
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
2 mai 2005 à 10:30
...euh... trouver si un nb est premier ou pas, est différent de savoir combien il y a de nombre premier inférieur à une borne... donc il me semble justifié que cela soit séparé... d'ailleurs c'est souvent le cas ici...

Ceci dit, les deux sources du calcul de pi(x) pourrait n'en faire qu'une à la rigueur... Mais est-ce le plus important ? non... l'important c'est de discuter sur le code et non sur la présentation du code... De plus, un code qui semble moins rapide, peut avec certains remarques se retrouver comme le plus efficace, d'où l'intérêt d'en mettre deux... et donc justement pour la clarté des propos, (pour savoir duquel on parle) il me semble normal d'avoir mis les 2 petits programmes séparés... en plus, je me vois mal, faire une explication détaillée de deux algorithmes différents dans le même post. Tout le monde, serait perdus... et moi, le premier...

Voilà donc, je pense m'être assez justifié... Je pense pas absuser, et toute personne honnête comprendra le but recherché...

PS : Dorénavant, je ne réponderai qu'aux remarques sur l'algo, et rien d'autre... et c'est aussi, me semble-t-il, un des buts du site... à savoir, perfectionner un code... et cela peut devenir un vrai défie (courtois, cela va s'en dire)...

Amicalement,
Us.
cs_Stephane Messages postés 550 Date d'inscription vendredi 5 janvier 2001 Statut Membre Dernière intervention 23 septembre 2006
1 mai 2005 à 20:58
le but des sources et de partager des connaissances, pas défier..
t'aurais quand meme pu regrouper les 3 sources en une seule (ayant toute le meme sujet...), et ca permet lors de recherche, d'avoir moins de résultats a parcourrir, et d'avoir plus d'infos.

a+
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
1 mai 2005 à 20:07
Non, pas 3 sources qui font la même chose ! Seulement 2... C'est pour le comparaison de leurs rapidités respectives ! Afin de mieux souligner le fait, que ce dernier est rapide... Alors, qui peut me trouver plus rapide ? (bien sur, hors test de proba...)
MadM@tt Messages postés 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
1 mai 2005 à 19:47
Pourquoi 3 sources à la suite qui font la meme chose ?