violent_ken
Messages postés1812Date d'inscriptionmardi 31 mai 2005StatutMembreDernière intervention26 octobre 2010
-
2 sept. 2005 à 19:04
PCPT
Messages postés13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 2018
-
4 sept. 2005 à 22:09
Violent Ken
Salut. Je suis en train de faire un algorithme de calcul, et j'aimerais l'optimiser au maximum.
Par exemple, est-il plus rapide de faire
for x=1 to 10
a=a+30
next x
ou
for x=1 to 30
a=a+10
next x
est-il plus rapide de faire
if a=1 then
else
end if
ou d'utiliser Iif
est-il plus rapide de faire
While a < 500
a = a + 1
Wend
ou
Do Until a = 500
a = a + 1
Loop
a=b^0.5 ou a=sqr(b)
Il y a des tas de possibilités pour faire une même action, et j'aimerais que vous me donniez des astuces pour pouvoir 'optimiser' au maximum le code.
Merci, @+
Note: je sais que le C est bien plus rapide que le VB, mais je compte faire mon algo en VB
cs_CanisLupus
Messages postés3757Date d'inscriptionmardi 23 septembre 2003StatutMembreDernière intervention13 mars 200621 3 sept. 2005 à 18:13
Pour le DoEvents, j'ai seulement dit "...est souvent nécessaire...", je n'ai pas dit indispensable. Et je rejoins us_30 et violent_ken sur ce point.
De toutes façons, tout dépend de ce qu'on veux faire. Comme on dit, on ne peux avoir le beurre ET l'argent du beurre (certains rajouteraient : ET le ... de la crémière).
Si on veut faire quelque chose de TRES performant on choisit le C ou l'ASM et si on n'a que VB, on suit les conseils que BruNews donne dans ces posts sur ce topic.
Dans tous les cas, il faut transiger, voir au cas par cas, surtout quand il s'agit d'applis avec interface utilisateur (dans ce cas, il faut même avoir des notions de psycho). Un utilisateur final se fout de savoir qu'une boucle met 1 ou 1000 millisecondes, ce qu'il voit c'est le résultat.
Il est bien évident, qu'en tant que programmeur, il faut se préoccuper de la perf de son code mais aussi de la perf apparente à l'utilisateur en terme d'ergonomie et de liberté.
Mettre un DoEvents dans une boucle qui ne mobilise pas trop de ressources, c'est bête.
Ne pas le mettre dans une boucle qui risque de mobiliser toutes les ressources du PC pendant 1/2 heure, c'est suicidaire. Même si on a prévenu l'utisateur (il peut vouloir lire ses mails ou jouer au solitaire en attendant ?).
En dehors du DoEvents, il y a aussi d'autres astuces qui n'ont (apparemment) rien à voir avec la prog pure. Comme placer certains traitements longs là ou l'utilisateur s'attend à ne pas recevoir une réponse immédiate....
-------------------------------------------------
Dresseur de puces, .... normal pour un loup !?
us_30
Messages postés2065Date d'inscriptionlundi 11 avril 2005StatutMembreDernière intervention14 mars 201610 3 sept. 2005 à 23:38
Bon Okay pour DoEvents, passons un peu à autre chose...
PCPT, Pour le Prog de test, je ne disais pas du mal... loin de moi cette idée... mais effectivement, perso, je pense qu'il faudrait bien prendre en compte le temps d'appel pour le déduire... C'est qu'une simple question de math pour la comparaison. Si deux procédures rapides sont trés proches l'une de l'autre, avec un temps d'appel non négligeable (proportionnellement), la comparaison deviendra nécessairement ardue ! ...
Autre chose. Dans les énumérations qu'on peut voir dans les tutos, je crois qu'il n'y a pas celle-ci. Pour le calcul des puissances au carré, il est beaucoup plus rapide de faire X*X que X^2 ... En fait, c'est même plus compliqué que cela... LES calculs X^3, X^4, etc... donnent un temps quasi-constant, qu'alors X*X*...*X augmentent avec le nb de X... En non compilé, les temps d'exécution s'équilibrent pour environ X^9... curieux non ? ... et bon à savoir...
Encore autre chose. Question peut-être bête, mais bon... existe-t-il un autre compilateur d'un listing VB meilleur que celui de Microsoft ? ... en évitant du code stupide comme le soulignait hier Brunews...
us_30
Messages postés2065Date d'inscriptionlundi 11 avril 2005StatutMembreDernière intervention14 mars 201610 4 sept. 2005 à 13:36
Voici une optimisation que je viens de trouver en remplacement de IF t mod 90=0 then ... c.a.d. exécuter un sous programme une fois tous les X fois... comme on en parlait...
LISTING 1 : Celui de base :
Sub essai()
temps = Timer
Dim t As Long
Dim a As Long
Dim b As Long
Dim bm As Long
bm = 10000000
For t = 0 To bm
If t Mod 90 0 Then a a + 1 'SP1
b = b + 1 'SP2
Next t
MsgBox Timer - temps & " " & a & " " & b
End Sub
LISTING 2 : L'optimisation qui réalise exactement la même chose :
Sub essai2()
temps = Timer
Dim t As Long
Dim a As Long
Dim b As Long
Dim bf1 As Long
Dim bf2 As Long
Dim j As Long
Dim bm As Long
bm = 10000000
bf1 = bm \ 90 - 1
For j = 0 To bf1
a = a + 1 'SP1
bf2 = j * 90 + 90 - 1
For t = j * 90 To bf2
b = b + 1 'SP2
Next t
Next j
a = a + 1 'SP1
For t = j * 90 To bm
b = b + 1 'SP2
Next t
MsgBox Timer - temps & " " & a & " " & b
End Sub
L'avantage du second est de plus en plus nette, dès le saut (ici 90) est important... En fait pour un saut de 2 fois, c'est le LISTING 1 le plus rapide, au delà c'est le second... Ici, pour 90, le LISTING 2 est environ 2,5 fois plus rapide que le premier...
Comme j'utilise cette structure dans qlq'uns de mes algos, j'ai déjà une optimisation conséquente...
Voilà, comme quoi, on va tarir le sujet tout de suite...
violent_ken
Messages postés1812Date d'inscriptionmardi 31 mai 2005StatutMembreDernière intervention26 octobre 20102 4 sept. 2005 à 19:43
Violent Ken
PCPT a dit "umm, j'aurais supposé que mon timer aurait bien servi et remué les foules....
(à tord apparemment....)"
Bah à minuit je dormais, et ce week end j'étais pas là...
Mais je ne manquerait pas de l'essayer, promis !
Quand au Doevents, le mettre à toutes les boucles sans utiliser un truc du style" if (a mod x)", c'est du suicide pur pour les performances du programme : une simple boucle
For x = 1 To 5000000
DoEvents
a = a + 1
Next
mettra 8 secondes sur mon PC
et
For x = 1 To 5000000
a = a + 1
Next
mettra 0.5 secondes....
Le doevents divise la vitesse par 16!!
Un nouvel essai avec la command Mod
Private Sub Form_Load()
For x = 1 To 5000000
If (x Mod 10000) = 0 Then DoEvents
a = a + 1
Next
End Sub
mettra environ 2 secondes....
Alors faut mieux envisager le doevents avec le mod, et doser la valeur 10000 en fonction du processeur, pour rendre la main de tps en tps en perdant le moins de vitesse possible.
Bon, grâce à PCPT je vais pouvoir tester mes algorithmes, et je jetterai aussi un oeil sur les sources de us_30 pour les nombres premiers....
En tout cas merci à tous, c'est sympa de m'aider !
@+
Vous n’avez pas trouvé la réponse que vous recherchez ?
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 4 sept. 2005 à 20:17
En fait on ne peut pas prédire vraiment le ralentissement du à DoEvents.
On passe à la ligne qui suit DoEvents SEULEMENT quand PeekMessage ne trouvera plus rien sur la pile d'appels du thread.
while PeekMessage
TranslateMessage
DispatchMessage
wend
Il est clair que ceci peut être une cata pour un calcul, le moindre clic souris nimporte où sur la fenêtre génère une rafale de messages, ne parlons pas de mouvement ou repaint, là c'est la misère totale.
C'est à ce genre de trucs qu'on comprend qu'il était plus que temps de changer ce langage, même si le passage à vb.net n'est pas toujours évident.
us_30
Messages postés2065Date d'inscriptionlundi 11 avril 2005StatutMembreDernière intervention14 mars 201610 4 sept. 2005 à 20:42
Bonsoir,
Juste une précision, je ne parlais pas de nombre premier ! -:); mais c'est sans importance... Bon, aller, j'arrête pour le moment de discuter sur les optimisations... intéressant du reste...
violent_ken
Messages postés1812Date d'inscriptionmardi 31 mai 2005StatutMembreDernière intervention26 octobre 20102 4 sept. 2005 à 20:49
Violent Ken
Us_30, j'ai parlé de nombres premiers car à l'origine, mon problème était d'optimiser ma source de calcul de nombres premiers. Je suis donc allé jeter un coup d'oeil sur tes sources pour voir tes déclaration des variables, l'utilisations des boucles (for/next ou while/wend)... pour pouvoir comparer à ce que j'avais fait !
Et BruNews, quoi qu'on en dise sur les doevents, il est possible (dans une certaine mesure) de prédire le ralentissement du à cette commande; j'ai fait une expérience :
for y=1 to 50000000
a=a+1
if (y mod X)=0 then doevents
next
J'ai fait plusieurs mesures du temps mis pour éxecuter cette boucle en fonction de X.
Et bien le temps d'exécution décroit de manière exponentielle quand X augmente, et on remarque que pour X>40, le temps ne décroit plus bcp. C'est donc cette valeur , X=40, que l'on conservera dans ce cas, puisqu'elle permet une vitesse quasi-maximum en rendant la main assez souvent.
PCPT
Messages postés13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 201847 4 sept. 2005 à 21:00
Violent_Ken, pour info avec tes valeurs (test unique) :
For x 1 To 5000000: DoEvents: a a + 1: Next
IDE : 16299,5548 ms
EXE : 15451,6381 ms
For x 1 To 5000000: a a + 1: Next
IDE : 523,3333 ms
EXE : 15,895 ms
For x 1 To 5000000: a a + 1: If (x Mod 10000) = 0 Then DoEvents: Next
IDE : 1427,7784 ms
EXE : 265,2508 ms
peut-être qu'on mélange un peu le temps de calcul par rapport aux ressources qu'il demande.
perso, pour des calculs, c'est la vitesse dont j'ai besoin. là je place également un DoEvents avec un Mod .. selon mes besoins. par contre, dès que le graphique y est lié (exemple, déplacement de boutons), là le DoEvents est systématique, même sur une boucle de 40.
pour le dernier exemple (boucle avec Mod), elle demandera un calcul de plus à chaque ligne ; ce n'est qu'une question de compromis.
ps : pour X=40, ce n'est que parce que plus il y a de calculs et plus le proc met de temps à les faire, jusqu'à ce qu'il atteigne son "seuil minimal" (si on peut dire)
sachant tout de même que ce X sera variable selon chaque PC
violent_ken
Messages postés1812Date d'inscriptionmardi 31 mai 2005StatutMembreDernière intervention26 octobre 20102 4 sept. 2005 à 21:09
Violent Ken
Je suis pas sur d'avoir bien compris ta remarque, pcpt (ou peut-être que c'est toi qui a pas bien compris la mienne, je ne sais pas)
Je disais juste que pour un programme de calcul, où l'on recherche des performances, mettre un simple "doevents" est catastophique, le tps d'exécution est énorme.
J'ai donc cherché a mettre un
if (y mod UneValeur)=0 then Doevents
pour faire un doevents de tps en tps, histoire que le programme ne perde pas totalement la main.
J'ai donc cherché à modifier la valeur UneValeur pour voir les différences de tps mises par mon PC pour effectuer la boucle.
Résulats : Le temps d'exécution décroit de façon exponentielle quand UneValeur augmente, mais comme toute fonction exponentielle décroissante, elle atteint une limite, et le tps d'exécution ne décroit guère plus pour UneValeur>40. J'en ai donc déduit que cette valeur de 40 est la bonne pour mon programme, puisque c'est elle qui me permet d'avoir une vitesse rapide tout en randant la main assez souvent.
C'est peut-être plus clair comme, cà.
@+
PCPT
Messages postés13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 201847 4 sept. 2005 à 21:32
Violent_ken -> j'avais bien compris ^^
BruNews -> oui, le Mod comsomme beaucoup, c'est pour çà que je précisais à Ken la différence entre la consommation et le temps d'execution. avec ce Mod, la boucle consommera +, mais sera + rapide. d'ou le fait du compromis entre la vitesse d'execution et les ressources que l'on veut fixer à certaines procédures....
For x 1 To 5000000: a a + 1: If (x And 8191) Then DoEvents: Next
IDE : 24370,9469
ms
EXE : 13858,3949 ms