[BASIC] Optimisation du calcul de xor
Posté le 11/11/2026 15:06
Je cherche comment optimiser le calcul de
xor entre deux octets en BASIC. À l'origine c'est pour générer les codes d'erreur de QR codes, mais ça pourrait potentiellement servir ailleurs... je suis preneur d'idées.
Il y a bien la commande
xor du mode BASE, qu'on peut utiliser en mode normal si on écrit l'opcode direct un g1m avec un éditeur hexadécimal (vu qu'il est pas dans la catalogue et qu'on peut pas copier/coller en mode BASE), mais ces commandes binaires sont leeeentes. Pour vous donner une idée, sur ma Graph 75+E, sans overclock :
For 0→I To 255:Iand255:Next
'7.30 s (!!)
For 0→I To 255:I Rmdr 256:Next
'1.30 s
C'est pas super étonnant dans la mesure où les nombres en BASIC sont stockés en BCD (en base 10) donc les opérations binaires sont pas rapides, mais là c'est vraiment catastrophique.
Du coup je cherche des alternatives arithmétiques. Voilà mon benchmark...
For 1→A To 4
Locate 1,1,A
For 100→I To 115
For 100→J To 115
IxorJ
Next:Next:Next:ClrText
'26.90 s (!!)
Dans la suite, tout reste fixe sauf la ligne
IxorJ.
La seule piste qui marche à peu près pour l'instant est de coder la fonction sur 4 bits dans une matrice 16×16 et de recombiner les deux moitiés à la main :
16MatA[1+I Int÷ 16,1+J Int÷16]+Mat A[1+I Rmdr 16,1+J Rmdr 16
'20.10 s
Sachant que
MatA[1+I,1+J] = IxorJ, précalculé.
J'ai aussi essayé dans une liste, en espérant que je gagnerais sur le calcul mélangé des indices :
16List 9[1+16(I Int÷ 16)+J Int÷ 16]+List 9[1+16(I Rmdr 16)+J Rmdr 16
'20.76 s
Avec
List 9[16I+J] = IxorJ, précalculé.
La variation où les bits du haut sont obtenus par soustraction est plus lente :
16List 9[1+I-(I Rmdr 16)+J Int÷ 16]+List 9[1+16(I Rmdr 16)+J Rmdr 16
'23.20 s
Je suis un peu à court d'idées, je me demandais si y'a pas moyen de tricher avec d'autres fonctions hardcodées, e.g. donner une expression de A xor B comme
List 1[A]+List 2[A+B], mais y'a pas de solution pour cette forme-là et je sais pas trop par quel autre bout la prendre.
Citer : Posté le 11/11/2026 17:56 | #
Je tiens un bon bout. La dernière version avec une liste a le bon goût de se prêter au calcul parallèle/fonctoriel sur les listes. Par exemple si on a 80 xor différents à calculer, xor lui-même ne prend pas de listes en argument donc faut le faire à la main et c'est lent :
Seq(X,X,41,120,1)→List 11
40→Dim List 12
For 1→X To 80
List 10[X]xorList 11[X→List 12[X
Next
' 3.45 s
Le calcul précédent est plus rapide de base :
List 10[X→I
List 11[X→J
16List 9[1+16(I Int÷ 16)+J Int÷ 16]+List 9[1+16(I Rmdr 16)+J Rmdr 16→List 12[X
Next
' 2.70 s
Mais aussi on peut paralléliser les Int÷ et Rmdr sur les listes, ce qui gagne pas mal de temps à ne pas re-parser tout le temps la même formule.
1+16(List 10 Rmdr 16)+List 11 Rmdr 16→List 14
For 1→X To 80
16 List 9[List 13[X]]+List 9[List 14[X→List 12[X
Next
' 1.80 s
Malheureusement, on ne peut pas écrire List 1[List 2] pour obtenir, à la Python, [List 1[x] for x in List 2]. Mais on peut faire un Seq() et gagner encore un peu plus de temps :
1+16(List 10 Rmdr 16)+List 11 Rmdr 16→List 14
Seq(16 List 9[List 13[X]]+List 9[List 14[X,X,1,80,1→List 12
' 1.20 s
Par contre pour le QR code une des listes est un intervalle d'une liste plus grande donc c'est pas clair comment faudrait l'adapter. Mais on gagne, je pense.