Défi: optimisation d'une fonction de convertion (Bin => Dec)
lcprog
Messages postés41Date d'inscriptionmardi 23 septembre 2003StatutMembreDernière intervention11 septembre 2006
-
4 janv. 2005 à 14:47
JoePatent
Messages postés171Date d'inscriptionjeudi 30 janvier 2003StatutMembreDernière intervention20 juillet 2008
-
4 janv. 2005 à 21:39
Salut!
J'ai besoin dans un programme d'avoir une fonction qui me converti en nombre entier une chaine de caractères représentative d'un nombre binaire strictement positif compris entre 0 et 511 ex: "100110100" (codage sur 9 bits).
Cette fonction doit être appelée environ 9 000 000 de fois à la suite. Il me faut donc qu'elle soit le plus rapide possible. Je poste la fonction que je me suis programmé mais que je voudrais optimiser.
Si vous avez des idée pour augmenter la rapidité du code je vous serai reconnaissant.
Merci!
Loïc
Private Function BinToNum(sBinary As String) As Long
Dim nValue As Long
Dim nCpt As Long
Dim nPow As Byte
nValue = 0
nCpt = 1
While nCpt <= Len(sBinary)
If Mid(sBinary, nCpt, 1) = "1" Then
nPow = Len(sBinary) - nCpt
nValue = nValue + (2 ^ nPow)
End If
nCpt = nCpt + 1
Wend
BinToNum = nValue
End Function
A voir également:
Défi: optimisation d'une fonction de convertion (Bin => Dec)
K@zuya
Messages postés306Date d'inscriptionvendredi 21 février 2003StatutMembreDernière intervention15 février 2016 4 janv. 2005 à 15:21
Salut, j'ai déjà eut exactement le même genre de PB et j'ai trouvé une solution pas mal du tout, on ne peut pas faire plus rapide, c'est imposible.
il te faut ecrire une fonction dans ce goût la:
Private Function BinToNum(sBinary As String) As Long
Select Case sBinary
Case "000000000"
BinToNum = 0
Case "000000001"
BinToNum = 1
Case "000000010"
BinToNum = 2
Case "000000011"
BinToNum = 3
etc.....
End Select
End Function
Oui mais tu va m'dire, hein, fo écrire tout ça, c'est trop long !!!
C'est pourquoi moi, j'ai d'abord écrit un petit programme qui m'écrit la fonction toute faite dans un fichier puis je fais un copier/coller, c'est pas plus compliqué que ça.
lcprog
Messages postés41Date d'inscriptionmardi 23 septembre 2003StatutMembreDernière intervention11 septembre 2006 4 janv. 2005 à 16:23
la solution de Kazuya me plait bien. je testerai ce soir...
Sinon un gars sur hardware.fr m'a beaucoup aidé. Voici où on a abouti (presque 50% de gain de temps).
private nPowerArray(1 to 9) as long
Private Function Bin9BitsToNum(sBinary As String) As Long
Dim nValue As Long
Dim nCpt As Long
nValue = 0
nCpt = 9
While nCpt > 0
If AscW(Mid$(sBinary, nCpt, 1)) = 49 Then
nValue = nValue + nPowerArray(nCpt)
End If
nCpt = nCpt - 1
Wend
JoePatent
Messages postés171Date d'inscriptionjeudi 30 janvier 2003StatutMembreDernière intervention20 juillet 2008 4 janv. 2005 à 16:44
"Salut, j'ai déjà eut exactement le même genre de PB et j'ai trouvé une solution pas mal du tout, on ne peut pas faire plus rapide, c'est imposible."
Cette solution n'est pas la plus rapide. Chaque 'case' sera verifier dans le cas de 511 par exemple.
Tant qu'a procéder ainsi, fait 9 if indépendant pour tester chaque BIT un a un. Plus rapide, plus simple, plus court, plus stable. Toujours et uniquement 9 conditions. Aucune boucle, aucune incémentation de variable etc etc.
*****
LCPROG -> tu semble hardcodé le nombre de bit a 9 si je me fie au vecteur. Donc...
Private Function Bin9BitsToNum(sBinary As String) As Integer
Dim nValue As Integer ' Prit la liberté de réduire la taille des variable
Dim nCpt As Integer ' Prit la liberté de réduire la taille des variable
nValue = val(right&(sBinary, 1) ' Tant qu'a initialiser aussi bien couper une itération
for nCpt = 8 to 1 step -1 ' Pas convaincu que cette boucle est plus performante
nValue = nValue + (nPowerArray(nCpt) * val(mid$(sBinary, nCpt, 1)))
next j
lcprog
Messages postés41Date d'inscriptionmardi 23 septembre 2003StatutMembreDernière intervention11 septembre 2006 4 janv. 2005 à 16:58
Voilà où j'en suis. J'ai pas trouvé plus rapide.
Private Function Bin9BitsToNum(sBinary As String) As Long
Dim nValue As Long
If AscW(Mid$(sBinary, 1, 1)) = 49 Then
nValue = nValue + 256
End If
If AscW(Mid$(sBinary, 2, 1)) = 49 Then
nValue = nValue + 128
End If
If AscW(Mid$(sBinary, 3, 1)) = 49 Then
nValue = nValue + 64
End If
If AscW(Mid$(sBinary, 4, 1)) = 49 Then
nValue = nValue + 32
End If
If AscW(Mid$(sBinary, 5, 1)) = 49 Then
nValue = nValue + 16
End If
If AscW(Mid$(sBinary, 6, 1)) = 49 Then
nValue = nValue + 8
End If
If AscW(Mid$(sBinary, 7, 1)) = 49 Then
nValue = nValue + 4
End If
If AscW(Mid$(sBinary, 8, 1)) = 49 Then
nValue = nValue + 2
End If
If AscW(Mid$(sBinary, 9, 1)) = 49 Then
nValue = nValue + 1
End If
Bin9BitsToNum = nValue
End Function
JoePatent, t'es sur pour l'integer ? J'ai lu qu'il fallait de préférence utiliser le tupe long en vb pour les processeurs 32 bits. Faut pas regarder la variable nLevel, c'est une propriété utilisée dans les autres méthodes de ma classe.
Gobillot
Messages postés3140Date d'inscriptionvendredi 14 mai 2004StatutMembreDernière intervention11 mars 201934 4 janv. 2005 à 18:30
l'accès direct est toujours le plus rapide, bien sûr ça prend énormément de place mais ensuite les temps sont negligeables.
Dim s As String
Dim i As Integer
Dim T() As Integer
ReDim T(111111111)
For i = 0 To 511
s = Byte2String(i)
T(Val(s)) = i
Next
Private Function Byte2String(n As Integer) As String
Dim x As Integer
Dim R As String
x = 256
Do If (n And x) Then R R + "1" Else R R + "0"
x = x \ 2
Loop Until x = 0
Byte2String = R
End Function
'pour l'utilsation accès directe dans la Table
Bin9BitsToNum = T(Val(sBinary))
JoePatent
Messages postés171Date d'inscriptionjeudi 30 janvier 2003StatutMembreDernière intervention20 juillet 2008 4 janv. 2005 à 21:39
Voici une autre possibilité :
L'astuce est d'éliminer les manipulations de chaîne de caractère. Seul le VAL() demeure et est tres tres gourmand.
J'obtiens 20 secondes au lieu de 29. Toutefois, si je recois un long au lieu d'ue string je descend a 10 secondes. Mais on a pas le choix j'imagine de recevoir une string :-(
Voici :
Private Function DBin9BitsToNum(sbinary As String) As Integer
Dim z As Long
Dim nValue As Integer
z = Val(sbinary)
nValue = nValue + (1 * (z Mod 2))
z = z \ 10
nValue = nValue + (2 * (z Mod 2))
z = z \ 10
nValue = nValue + (4 * (z Mod 2))
z = z \ 10
nValue = nValue + (8 * (z Mod 2))
z = z \ 10
nValue = nValue + (16 * (z Mod 2))
z = z \ 10
nValue = nValue + (32 * (z Mod 2))
z = z \ 10
nValue = nValue + (64 * (z Mod 2))
z = z \ 10
nValue = nValue + (128 * (z Mod 2))
z = z \ 10
nValue = nValue + (256 * (z Mod 2))