Seuls les membres ayant 30 points peuvent parler sur le chat.

Forum Casio - Vos tutoriels et astuces


Index du Forum » Vos tutoriels et astuces » Réduire la taille du programme
SmashmasterHors ligneAncien modérateurPoints: 4559 Défis: 253 Message

Réduire la taille du programme

Posté le 25/05/2011 22:12

Si vous programmez un jeu ou un programme il est important de l'optimiser au maximum au niveau taille et vitesse, voici de petites astuces pour optimiser vos programmes :

Le drawstat
Cliquez pour découvrir
Cliquez pour recouvrir
Le Drawstat est une méthode pour dessiner rapidement des trucs sur l'écran de la calculatrice, plus rapidement qu'avec des F-lines. voici des tuto pour apprendre le drawstat: Tuto de Dafp ou Tuto de neuronix

Optimiser les conditions
Cliquez pour découvrir
Cliquez pour recouvrir

Voici une condition avant l'optimisation :
If A>C
Then 3->B[DISP]
Else 8->B[DISP]
IfEnd

Et maintenant cette même condition après l'optimisation :
8-5(A>C)->B[DISP]

Littéralement: Si A>C, alors B vaut 8-5=3, sinon B vaut 8
En effet le chiffre cinq sera uniquement pris en compte dans le calcul si A>C.
Autres exemples pour mieux comprendre:

3->A
4->B
5->C
6->D

8(A>C)+5+3(A=<C)->E[DISP]       //si A>C, alors E=8+5=13, sinon E=5+3=8, dans ce cas A<C donc E=8

(6B/D+3)(A<C)+5+(10C/D+3)(Not A)->E[DISP]       //si A<C et A!=0 alors E=(6B/D+3)+5+(10C/D+3) ...


If J=1
Then Mat M[1,1]->A
Mat S[1,2]->B
Else
Mat M[2,2]->A
Mat S[2,3]->B
IfEnd

s'écrit aussi :

Mat M[2,2](J!=1)+Mat M[1,1](J=1)->A
Mat S[2,3](J!=1)+Mat S[1,2](J=1)->B


Les vitesses d’exécutions :
For 1->A To 2000
If A>C
Then 5->C
Else 3->C
IfEnd
Next

//Vitesse sur la prizm underclocké à 54.4 Mhz : 9.31s
//Vitesse sur la G75 : 8.3s
For 1->A To 2000
3+2 (A>C->C
Next

//Vitesse sur la prizm underclocké à 54.4 Mhz : 7.84s
//Vitesse sur la G75 : 8.46s

Sur la G75 cette astuce est plus lente, mais elle est plus rapide sur la prizm (cg10/20).

Les sous programmes
Cliquez pour découvrir
Cliquez pour recouvrir
Imaginons un gros programme qui contient plusieurs fois des répétitions, exemple :

[u]nom du programme: MENU[/u]
...
// Truc 1
...
Do
Getkey
LpWhile Not Ans
...
// Truc 2
...
Do
Getkey
LpWhile Not Ans
...
// Truc 3
...
Do
Getkey
LpWhile Not Ans
// truc 4
...
On observe qu'il y a des répétitions.
On peut optimiser ce programme en mettant la partie répétée dans un sous prog, on obtient ceci :

[u]nom du programme: MENU[/u]
...
// Truc 1
...
Prog "GETKEY"
...
// Truc 2
...
prog "GETKEY"
...
// Truc 3
...
prog "GETKEY"
...
// truc 4
...

[u]nom du programme: GETKEY[/u]

Do
Getkey
LpWhile Not Ans
Les sous prog améliore aussi la lisibilité du code

Utiliser des variables
Cliquez pour découvrir
Cliquez pour recouvrir
Voici un programme avant l'optimisation :
{2565166,2565166,2565166,2565166,2565166,2565166,1451,1546,
444,2565166,2565166,2565166,2565166,2565166->List 1

Et maintenant ce même programme après l'optimisation :
[u]Premier possibilité :[/u]
2565166->A
{A,A,A,A,A,A,1451,1546,444,A,A,A,A,A->List 1


[u]Deuxième possibilité :[/u]
2565166
{Ans,Ans,Ans,Ans,Ans,Ans,1451,1546,444,Ans,Ans,Ans,Ans,Ans->List 1

Remarque 1 : Dans ce cas les '}' sont inutiles
Remarque 2 : Ans est une variable qui contient la valeur du dernier résultat, ici Ans vaut 2565166
J'ai tout simplement stocké le nombre 2565166 dans la variable A ;). Une autre possibilité est d'utiliser la variable Ans qui permet d'optimisé encore mieux vos programmes
Autres exemples :


[u]Avant :[/u]

(Mat S[1,4]+AxMat S[1,4])xMat S[1,4]->E

[u]Après :[/u]

Mat S[1,4]->B
(B+AB)B->E
ou encore (avec Ans) :
Mat S[1,4]
(Ans+AxAns)Ans

Do
Getkey=31=>1->A
Getkey=41=>2->A
Getkey=51=>3->A
Getkey=61=>4->A
Getkey=71=>5->A
Getkey=32=>6->A
Getkey=42=>7->A
Getkey=52=>8->A
(89 octets)

devient

Do
Getkey
Ans=31=>1->A
Ans=41=>2->A
Ans=51=>3->A
Ans=61=>4->A
Ans=71=>5->A
Ans=32=>6->A
Ans=42=>7->A
Ans=52=>8->A  
(67 octets)


Combien de variables existe-t-il ? Beaucoup de personnes pensent qu'il y en a 28 (Toutes les lettres de l'alphabet, r et [TETA] ), mais en réalité il y en a 37 (peut être même plus) :
Les variables supplémentaires sont a0, a1, a2, b0, b1, b2, c0, c1 et c2, on les trouve dans [VARS]+[F6]+[F2]+[2] pour les Graph 100 (+) ou dans [VARS]+[F6]+2x[F2] pour les autres calculatrices

Dans cette partie du cours on admettra ceci : une variable existe si elle ne vaut pas 0 et une variable n'existe pas si elle vaut 0. Exemple : soit une variable A, la variable A existe si A != 0 et elle n'existe pas si A=0
Voici un programme avant l'optimisation :

If A!=0
Then ...
IfEnd
If B=0
Then ...
IfEnd

Et maintenant ce même prog après l'optimisation :

If A
Then ...
IfEnd
If Not B
Then ...
IfEnd    

La première ligne signifie ''Si A existe'' c'est-à-dire ''Si A !=0''
La quatrième ligne signifie ''Si B n'existe pas'' c'est-à- dire ''Si B = 0''

Syntaxe globale :
''<variable> = 0'' s'écrit aussi ''Not <variable>'' (optimisation de 1 octet, c'est déjà pas mal)
''<variable> != 0'' s'écrit aussi ''<variable>'' (optimisation de 2 octets)
On peut aussi appliquer cette méthode dans les boucles, exemple :

Do
...
LpWhile A=0 And B!=0

donne:

Do
...
LpWhile Not A And B     (optimisation de 3 octets)

Eviter les goto/Lbl
Cliquez pour découvrir
Cliquez pour recouvrir
Les Labels (c'est-à-dire les Goto/Lbl) sont très utilisés en programmation mais malheureusement les labels ont deux gros défauts :
Ils sont lent:

0->A
Lbl 1
A+1->A
A<1000=> Goto 1  ce programme est exécuté en 12,5 secondes

0->A
Do
A+1->A
LpWhile A<1000     ce programme est exécuté en 11,1 secondes

Dans cet exemple il n'y a pas beaucoup de différence au niveau de la vitesse, mais dans un gros programme la lenteur est bien plus marquée
Ils bug si on les utilise mal:
Exemple de programme qui bug:
1->A
If A=1
Then Lbl 1
...
'truc 1
...
IfEnd
...
'truc 2
...
5->B
B=5=>Goto 1

Il y a un Syn Err au niveau du IfEnd, pourquoi ?
Ce programme bug, car un moment donné la calculatrice rencontre deux IfEnds et un If+Then donc la calculatrice pense qu'il y a un IfEnd en trop, d'où le bug ... En gros la calculatrice lit :
1->A
If A=1
Then Lbl 1
...
'truc 1
...
IfEnd
...
'truc 2
...
5->B  
la calculatrice lis B=5=>Goto 1 or B=5 donc elle cherche Lbl 1
...
'truc 1
...
IfEnd
la calculatrice n'ignore pas le IfEnd

Il est assez difficile de corriger ces bug parce que l'erreur n'est pas très visible, d'où la nécessité d'utiliser moins de labels

Comment contourner ces problèmes ? Tout simplement en utilisant moins de labels et plus de boucles (boucle For, Do-LpWhile, While ...), le mieux c'est de ne plus utiliser de label
Remarque : les labels (c'est-à-dire les Goto/Lbl) ne sont pas des boucles !

Les petites optimisations
Cliquez pour découvrir
Cliquez pour recouvrir
Voici des optimisations qui ne modifient pas grand-chose la taille du prog, mais qui peuvent être utiles.

0.6+0.4A+0.2B->E s'écrit aussi .6+.4A+.2B->E ,dans ce cas les zéros sont inutiles, la calculatrice comprend que 0.6 = .6

5(2A(3+A(4-A(5-A(A+B+C+D)))))->E s'écrit aussi 5(2A(3+A(4-A(5-A(A+B+C+D->E , dans ce cas les parenthèses ')' à la fin ne servent à rien

1/A s'écrit aussi A^-1, pour obtenir ^-1 il suffit d'appuyer respectivement sur les touches [shift] puis [)].

5000000000000 s'écrit aussi 5*10^12 ou encore 5E12, pour obtenir le 'E' il suffit d'appuyer sur la touche [x10^x], cette touche se trouve en bas de la calculatrice
autre exemple: 0.000000000005 = 5E-12
Attention : 100000A ne s'écrit pas AE5 (Erreur syntaxe), dans ce cas il faut écrire Ax1E5

Pour tout ce qui est puissances de 10, il y a aussi le menu ESYM ( [OPTN][F5][5] sur la g100(+) et [OPTN] [F6] [F6] [F1] sur les autres modèles) qui contient les symboles milli, micro, nano, pico, femto, kilo, mega, giga, tera, péta.
On peut par exemple écrire 1k pour avoir 1000, 5T pour avoir 5x10^12 ...

{500,501,502->List 1 s'écrit aussi 500+{0,1,2->List 1, dans cet exemple chaque valeur de la List 1 est additionné par 500
Bien évidemment on n'est pas obligé d'utiliser des +, on peut très bien utilisé les autres signes mathématiques

Liens intéressants:


Quelques exercices d'optimisation

Exercices
Exercices

Optimiser ce programme :

Filename: BIDULE

{100000000,200000000,300000000,400000000,500000000,600000000,
700000000,800000000,900000000,1000000000}->List 1
{25,5651,505,1,561,65,165,51,52,651,5}->List 2
0->A
Do
Getkey=31=>1->A
Getkey=41=>2->A
Getkey=51=>3->A
Getkey=61=>4->A
Getkey=71=>5->A
LpWhile A=0
3->C
If A<C
Then 8->D
Else 5->D
IfEnd
D[DISP]
Text 1,1,"SALUT"
Do
Getkey
LpWhile Ans=0
Cls
Text 1,1,"JE SUIS SMASHMASTER"
Do
Getkey
LpWhile Ans=0
Cls
Text 1,1,"JE SUIS MEMBRE DEPUIS 2009"
Do
Getkey
LpWhile Ans=0
Cls
Text 1,1,"J'AIME PC "
Do
Getkey
LpWhile Ans=0
Cls
Drawstat


Solution:
Il existe plusieurs méthodes pour optimiser ce code, voici en une:

Filename: BIDULE
1E8x{1,2,3,4,5,6,7,8,9,10->List 1
{25,5651,505,1,561,65,165,51,52,651,5->List 2
Prog GETKEY
Int .1Ans-2->A
5+3(A<3->D
D[DISP]
Text 1,1,SALUT
Prog GETKEY
Text 1,1,JE SUIS SMASHMASTER
Prog GETKEY
Text 1,1,JE SUIS MEMBRE DEPUIS 2009
Prog GETKEY
Text 1,1,J\'AIME PC
Prog GETKEY
Drawstat

Filename : GETKEY

Do
Getkey
LpWhile Not Ans
Cls




Pages : Précédente1, 2, 3
Mgl64200Hors ligneMembrePoints: 649 Défis: 0 Message

Citer : Posté le 30/03/2015 12:41 | #


Oi c'est ce que je dis si tu fais toutes les optis, le gain est déja assz conséquent, la technique seule ne suffit pas
Toi t'es en train de lire ma signature là...
FabcvlrHors ligneMembrePoints: 2179 Défis: 41 Message

Citer : Posté le 31/03/2015 09:04 | #


Avec le Locate, le Dips"◢" ne provoque pas de problème si on a enlevé le guillemet mais curieusement le ◢ est affiché en bout de ligne !
L'expérience des autres, c'est comme une chandelle que l'on tient allumée dans son dos par une nuit de tempête !
Mgl64200Hors ligneMembrePoints: 649 Défis: 0 Message

Citer : Posté le 25/04/2015 17:41 | #


Et c'est pas un octet gagné lorsqu'on enlève un ", mais 4.
Toi t'es en train de lire ma signature là...
Dark stormEn ligneMembre d'honneurPoints: 10834 Défis: 176 Message

Citer : Posté le 25/04/2015 18:24 | #


Absolument pas
Tu gagne 4 octets dans le cas où ton programme descend en dessous d'un multiple. Exemple en mémoire
Locate 1,1,"Hi" // 2 + 8 octets = 10 octets, le programme fait 12 en mémoire (multiple de 4)

Locate 1,1,"Hi // 2 + 7 octets = 9 octets, le programme en fait 12 en mémoire

Locate 1,1,"H // 2 + 6 octets = 8 octets, le programme en fait 8 en mémoire (gain apparent de 4 octets)


Mais en aucun cas enlever un « " » réduit de 4 octets la taille du programme !
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
LephenixnoirEn ligneAdministrateurPoints: 16161 Défis: 140 Message

Citer : Posté le 25/04/2015 19:25 | #


Je pense qu'on peut dire que 4 octets est la taille d'un cluster de la mémoire principale...
Mgl64200Hors ligneMembrePoints: 649 Défis: 0 Message

Citer : Posté le 25/04/2015 20:36 | #


Au temps pour moi, mais un byte = un octet ?
Toi t'es en train de lire ma signature là...
DarkysunHors ligneMembrePoints: 1747 Défis: 52 Message

Citer : Posté le 25/04/2015 20:42 | #


Je crois qu'un byte=un octet mais un byte=huit bits
Si je ne réponds pas à un post depuis trop longtemps : envoyez-moi un message pour me le rappeler !




SmashmasterHors ligneAncien modérateurPoints: 4559 Défis: 253 Message

Citer : Posté le 25/04/2015 20:44 | #


Oui
1 Octet = 8 Bits
1 Octet = 1 Byte
1 Byte = 8 Bits
Tilde
Statut : Invité

Citer : Posté le 15/04/2016 03:02 | #


The byte is the smallest addressable unit of memory in many computer architectures. The size of the byte has historically been hardware dependent and no definitive standards existed that mandated the size.

Souvent, 1 Byte = 8 bits, mais Byte n'est pas le mot anglais équivalent d'Octet.

En anglais, octet se dit... octet.
RedcmdHors ligneMembrePoints: 200 Défis: 5 Message

Citer : Posté le 26/08/2019 07:20 | #


Do
Getkey
LpWhile Not Ans
can be optimized to
Do : LpWhile Not Getkey


Only using one " (Double Quotes) can cause issues (fx-9680GII)
When using Labels/Goto
Lbl A
If 0
Then Text 1, 1, "Hi
IfEnd
Goto A
This code runs once then stops
When it should loop infinitely

For me 'Not' is 2bytes
So replacing '=0' with 'Not' does nothing
RedCMD#4299 - Discord
Mandelbrot SNKEmini Minesweeper Sudoku
LephenixnoirEn ligneAdministrateurPoints: 16161 Défis: 140 Message

Citer : Posté le 26/08/2019 09:05 | #


Redcmd a écrit :
Do
Getkey
LpWhile Not Ans
can be optimized to
Do : LpWhile Not Getkey

Won't you lose the key code stored in Ans in this case?

For me 'Not' is 2bytes
So replacing '=0' with 'Not' does nothing

Not in terms of program size, but parsing probably happens differently. In the end, a quick manual test of X=0 against Not X in a 1000-iteration loop suggests that Not x (3.0s) is much faster than X=0 (3.4s, remember the overhead of the loop).
RedcmdHors ligneMembrePoints: 200 Défis: 5 Message

Citer : Posté le 26/08/2019 09:13 | #


Lephenixnoir a écrit :
Will not you lose the key code stored in Ans in this case?
I wasn't looking at the top GetKey
I just looked at the bottom GeKey's which didn't use Ans
Thank you for spotting it

Lephenixnoir a écrit :
X=0 against Not X in a 1000-iteration loop suggests that Not x (3.0s) is much faster than X=0

I just did a test with x=0 vs Not X
0 -> X
For 1 -> A To 4000
Not X
next
and it came back at exactly the same amount of time (14.5sec)

I guess it looks a bit better anyway
RedCMD#4299 - Discord
Mandelbrot SNKEmini Minesweeper Sudoku
LephenixnoirEn ligneAdministrateurPoints: 16161 Défis: 140 Message

Citer : Posté le 26/08/2019 09:18 | #


Tried it again with your exact program and I consistently get 10% faster by using Not on my Graph 75+E. This may depend on the model...
RedcmdHors ligneMembrePoints: 200 Défis: 5 Message

Citer : Posté le 26/08/2019 09:27 | #


I have fx-9750GII
With the upgraded OS to fx-9860GII

OPTN F6 F6 F4 F3
For Not
RedCMD#4299 - Discord
Mandelbrot SNKEmini Minesweeper Sudoku
LephenixnoirEn ligneAdministrateurPoints: 16161 Défis: 140 Message

Citer : Posté le 26/08/2019 09:35 | #


Yeah, that's the same function and almost the same model as well. I ought to mention I have OS 02.05, but this performance gain has been discussed for years now so it shouldn't be this specific.

I guess I'll leave it here for the records...
RedcmdHors ligneMembrePoints: 200 Défis: 5 Message

Citer : Posté le 26/08/2019 09:49 | #


I have OS 2.04.0201
and Im running on 1.2V recharagable battries
RedCMD#4299 - Discord
Mandelbrot SNKEmini Minesweeper Sudoku
KirafiHors ligneMembrePoints: 2113 Défis: 10 Message

Citer : Posté le 26/08/2019 10:46 | #


Maybe you will share which method you use .

And as I said (can't remember the topic), the battries affects a little the performances, so maybe the difference is there.
iPod
Pour des parties rapides
Jusqu'où pourras-tu aller dans ce jeu "partie rapide" qu'est Dextris (élu Jeu Du Mois)
Pourras-tu survivre plus de 20 secondes dans ce fameux tunnel appelé Graviton
Rebondis entre les murs en évitant les piques dans SpikeBird
Pourras-tu éviter de te faire écraser dans FallBlocs (élu Jeu Du Mois)
Autres
Franchement ils valent le coups
Deviens l'amiral de la marine dans SeaRush (jeu concours) (élu Jeu Du Mois)
La version 2048 tactile amélioré au plus haut point : 2048 Delux !
Pars à la recherche des morceaux d'étoile dans Lumyce (élu Jeu Du Mois)
LephenixnoirEn ligneAdministrateurPoints: 16161 Défis: 140 Message

Citer : Posté le 26/08/2019 10:55 | #


Influencing performance is one thing, but doing so non-uniformly feels really way off to me...
Pages : Précédente1, 2, 3

Planète Casio v42 © créé par Neuronix et Muelsaco 2004 - 2019 | Il y a 136 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd