Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Benchmark du dimanche

15 réponses
Avatar
Jean-Marc
Hello à tous,

j'ai fait quelques tests de performances sur les fonctions
Asc vs AscW, et Chr$ vs ChrW$. Egalement testé la différence
entre s="" et s=vbNullSTring et enfin if s="" contre
If lenB(s) = 0. De quoi être étonné. Tous les résulats ici:
http://myjmnhome.dyndns.org/B2006/benchfunc.htm

Pour des programmes ou algorithmes faisant un usage intensif de
ces fonctions, on peut avoir un sacré gain (j'ai gagné un facteur
2 dans certaines parties critiques de Rabbit).

A utiliser bien sur a bon escient: pas la peine d'employer
des fonctions rapides dans un algorithme médiocre ou pas
adapté; Il vaut mieux utiliser un Chr$() dans un algo en
n.Log(n) qu'un ChrW$() dans un algo en n² :-))

--
Jean-marc
Tester mon serveur (VB6) => http://myjmnhome.dyndns.org
"There are only 10 kind of people
those who understand binary and those who don't."
mailto: remove '_no_spam_' ; _no_spam_jean_marc_n2@yahoo.fr

10 réponses

1 2
Avatar
Picalausa François
"Jean-Marc" a écrit dans le message de news:
43e5d14a$0$13893$
Hello à tous,

j'ai fait quelques tests de performances sur les fonctions
Asc vs AscW, et Chr$ vs ChrW$. Egalement testé la différence
entre s="" et s=vbNullSTring et enfin if s="" contre
If lenB(s) = 0. De quoi être étonné. Tous les résulats ici:
http://myjmnhome.dyndns.org/B2006/benchfunc.htm



Hello,

Pas très étonnant en fait... Je m'explique :
Il faut savoir que VB travaille en interne en UNICODE (fonctions en W). Par
conséquent, toutes les fonctions travaillant sur un charset différent (Asc,
Chr$) prennent un temps de conversion supplémentaire.

Normalement, en faisant le dernier test en comparant Len à LenB, il devrait
aussi y avoir une différence parce que LenB effectue une division par 2
supplémentaire pour tenir compte de cette même différence.

La différence entre les Asc, par exemple, vient probablement du fait que
dans le caractère ANSI a plusieurs "traductions" possibles en fonction des
paramètres régionaux, charset, ... là où AscW n'a qu'un accès mémoire à
faire, vers le pointeur qui lui est passé, et copymemory la valeur vers un
integer.

La différence entre
LenB(s) = 0 et s = ""
vient de la structure du BSTR (connu ici sous le nom de VB String). Le BSTR
possède une indication de la longueur avant la chaine sur 4 octets (ce qui
explique la limitation de 2147483648 caractères par chaines, puisqu'il
s'agit de 2 octets par caractères avec une valeur apparement signée). LenB
va donc rechercher cette information. s = "" au contraire crée une chaine de
caractère vide et ensuite lance une comparaison "caractère par caractère"
(qui s'arrête vite, mais pas si vite que ça).
Avec du s = vbNullString, les différences devraient être moins
importantes (aucune allocation de mémoire supplémentaire nécessaire).

Un autre phénomène semblable est celui de l'utilisation des API "A vs W".
Mis à par les considérations de support sur telle ou telle plateforme, la
version W est souvent plus rapide car VB ne doit pas prendre la peine de
faire la conversion UNICODE -> ANSI (automatiquement, mais malgré tout...).
La solution la plus efficace étant AMHA d'encapsuler ces fonctions dans une
typelib de sorte à ce que leur utilisation soit transparente (a noter qu'une
typelib ne doit pas être fournie avec l'installation), sinon il faut passer
par StrPtr (qui n'était pas supporté - et l'est encore moins maintenant?)...

--
Picalausa François
Avatar
Jean-Marc
"Picalausa François" a écrit dans le message de
news:
"Jean-Marc" a écrit dans le message de


news:
43e5d14a$0$13893$
> Hello à tous,
>
> j'ai fait quelques tests de performances sur les fonctions
> Asc vs AscW, et Chr$ vs ChrW$. Egalement testé la différence
> entre s="" et s=vbNullSTring et enfin if s="" contre
> If lenB(s) = 0. De quoi être étonné. Tous les résulats ici:
> http://myjmnhome.dyndns.org/B2006/benchfunc.htm

Hello,

Pas très étonnant en fait... Je m'explique :
Il faut savoir que VB travaille en interne en UNICODE (fonctions en


W). Par
conséquent, toutes les fonctions travaillant sur un charset différent


(Asc,
Chr$) prennent un temps de conversion supplémentaire.

Normalement, en faisant le dernier test en comparant Len à LenB, il


devrait
aussi y avoir une différence parce que LenB effectue une division par


2
supplémentaire pour tenir compte de cette même différence.

La différence entre les Asc, par exemple, vient probablement du fait


que
dans le caractère ANSI a plusieurs "traductions" possibles en fonction


des
paramètres régionaux, charset, ... là où AscW n'a qu'un accès mémoire


à
faire, vers le pointeur qui lui est passé, et copymemory la valeur


vers un
integer.

La différence entre
LenB(s) = 0 et s = ""
vient de la structure du BSTR (connu ici sous le nom de VB String). Le


BSTR
possède une indication de la longueur avant la chaine sur 4 octets (ce


qui
explique la limitation de 2147483648 caractères par chaines, puisqu'il
s'agit de 2 octets par caractères avec une valeur apparement signée).


LenB
va donc rechercher cette information. s = "" au contraire crée une


chaine de
caractère vide et ensuite lance une comparaison "caractère par


caractère"
(qui s'arrête vite, mais pas si vite que ça).
Avec du s = vbNullString, les différences devraient être moins
importantes (aucune allocation de mémoire supplémentaire nécessaire).

Un autre phénomène semblable est celui de l'utilisation des API "A vs


W".
Mis à par les considérations de support sur telle ou telle plateforme,


la
version W est souvent plus rapide car VB ne doit pas prendre la peine


de
faire la conversion UNICODE -> ANSI (automatiquement, mais malgré


tout...).
La solution la plus efficace étant AMHA d'encapsuler ces fonctions


dans une
typelib de sorte à ce que leur utilisation soit transparente (a noter


qu'une
typelib ne doit pas être fournie avec l'installation), sinon il faut


passer
par StrPtr (qui n'était pas supporté - et l'est encore moins


maintenant?)...

Hello François,

Merci pour les explications détaillées de tout cela! Pour la petite
histoire,
cette façon de stocker les chaines (longueur en tête sur 2 ou 4 octets)
est
la façon utilisée par la plupart des Basics depuis les origines. Pascal
fait
(ou faisait?) la même chose. L'avantage est comme tu le dis un calcul de
longueur
instantané, le prix à payer est qu'il faut mettre à jour cette valeur
dès qu'on
touche à la chaine (d'ou le fait que les manipulations de chaines en VB
(en
utilisant les focntions standards) soient peu performantes.

--
Jean-marc
Tester mon serveur (VB6) => http://myjmnhome.dyndns.org
"There are only 10 kind of people
those who understand binary and those who don't."
mailto: remove '_no_spam_' ;
Avatar
TouTi
Bonjour

C'est vraiment intéressant....

et qu'en est-t-il de l'écriture d'une conditionnelle incluse dans une boucle

--- Il vaut mieux ---

If toto=vbnullstring then
recup="il n'y a pas de données"
exit for
end if

--- que ----

If toto=vbnullstring then recup="il n'y a pas de données" : exit for

---???---

--
Guy
Avatar
Jean-Marc
"TouTi" <gelapplication[nospam]@tiscali.fr> a écrit dans le message de
news:43e72a9f$0$20174$
Bonjour

C'est vraiment intéressant....

et qu'en est-t-il de l'écriture d'une conditionnelle incluse dans une


boucle

--- Il vaut mieux ---

If toto=vbnullstring then
recup="il n'y a pas de données"
exit for
end if

--- que ----

If toto=vbnullstring then recup="il n'y a pas de données" : exit for

---???---



Hello,

La première forme. la seconde n'apporte rien, sinon la confusion.
Note: tant que possible, on évite les Exit For (ce n'est pas un crime
de l'utiliser, mais avec parcimonie). On préfèrera dans ce cas un
DO .. LOOP ou équivalent avec condition de sortie explicite.

--
Jean-marc
Tester mon serveur (VB6) => http://myjmnhome.dyndns.org
"There are only 10 kind of people
those who understand binary and those who don't."
mailto: remove '_no_spam_' ;
Avatar
Aski
Salutatoi Jean-Marc,

Tu as donc déclaré :

La première forme. la seconde n'apporte rien, sinon la confusion.
Note: tant que possible, on évite les Exit For (ce n'est pas un crime
de l'utiliser, mais avec parcimonie). On préfèrera dans ce cas un
DO .. LOOP ou équivalent avec condition de sortie explicite.



Je suppose que, même dans le cas de la boucle, il est préférable d'éliminer
le 'exit do' et préférer 'loop until condition'.
Avatar
Barsalou
Salut
Attention : asc et ascW ne renvoient pas la même valeur pour les caractères
qui ne sont pas de l'ASCII strict.
exemple:
si s = chr$(146)
asc(s) donne 146
ascW(s) donne 8217
Je me suis fait piéger en remplaçant dans un code tous les asc par ascW.
Avatar
Jean-Marc
"Aski" a écrit dans le message de
news:
Salutatoi Jean-Marc,

Tu as donc déclaré :

> La première forme. la seconde n'apporte rien, sinon la confusion.
> Note: tant que possible, on évite les Exit For (ce n'est pas un


crime
> de l'utiliser, mais avec parcimonie). On préfèrera dans ce cas un
> DO .. LOOP ou équivalent avec condition de sortie explicite.

Je suppose que, même dans le cas de la boucle, il est préférable


d'éliminer
le 'exit do' et préférer 'loop until condition'.



Hello,

Bien entendu, tu as raison. Il faut toujours préférer les sorties
explicites aux ruptures de séquences (exit ...) car cela revient à
un Goto déguisé. Pas très grave car c'est alors un saut en avant
vers une étiquette implicite, mais quand même. Rompre la linéarité
n'est (presque) jamais la meilleure solution.

--
Jean-marc
Tester mon serveur (VB6) => http://myjmnhome.dyndns.org
"There are only 10 kind of people
those who understand binary and those who don't."
mailto: remove '_no_spam_' ;
Avatar
Aski
Salutatoi Jean-Marc,

Tu as donc déclaré :

"Aski" a écrit dans le message de
news:
Salutatoi Jean-Marc,

Tu as donc déclaré :

La première forme. la seconde n'apporte rien, sinon la confusion.
Note: tant que possible, on évite les Exit For (ce n'est pas un
crime de l'utiliser, mais avec parcimonie). On préfèrera dans ce
cas un DO .. LOOP ou équivalent avec condition de sortie explicite.



Je suppose que, même dans le cas de la boucle, il est préférable
d'éliminer le 'exit do' et préférer 'loop until condition'.



Hello,

Bien entendu, tu as raison. Il faut toujours préférer les sorties
explicites aux ruptures de séquences (exit ...) car cela revient à
un Goto déguisé. Pas très grave car c'est alors un saut en avant
vers une étiquette implicite, mais quand même. Rompre la linéarité
n'est (presque) jamais la meilleure solution.



Pour être complets ajoutons que le seul GoTo admis par les puristes est
celui de 'On Error GoTo'. Il s'ensuit d'ailleurs presqu'obligatoirement un
Exit Sub pour éviter la gestion d'erreur.
Avatar
Jean-Marc
"Barsalou" a écrit dans le
message de news:
Salut
Attention : asc et ascW ne renvoient pas la même valeur pour les


caractères
qui ne sont pas de l'ASCII strict.
exemple:
si s = chr$(146)
asc(s) donne 146
ascW(s) donne 8217
Je me suis fait piéger en remplaçant dans un code tous les asc par


ascW.

Hello,

oui, tout à fait. Ces 2 fonctions sont équivalentes pour
l'ASCII, tel que défini par la norme (7 bits, valeurs 0 à 127).
Pour les valeurs supérieures (on parle parfois d'ASCII étendu),
ces 2 fonctions ne sont plus équivalentes.

Pour la norme ASCII, voir par exemple
http://alis.isoc.org/glossaire/iso646.10646.fr.htm


A noter quand même que les fonctions sont consistantes:

ascW(chr$(145)) = 8216 = le signe ' (backquote)

? chrw$(8216)
'

et bien sur:
? chr$(145)
'

Donc tout va bien :-)

--
Jean-marc
Tester mon serveur (VB6) => http://myjmnhome.dyndns.org
"There are only 10 kind of people
those who understand binary and those who don't."
mailto: remove '_no_spam_' ;
Avatar
Patrice Henrio
Pour ce qui est du "do loop", les différentes possibilités d'écriture sont
très variées mais seules l'utilisation du "exit d"o permet une boucle
contrôlé avec partie de traitement avant sortie et partie de traitement
avant boucle même si dans la plupart des cas on peut faire autrement il y a
des situations ou ce exit do est bien pratique. Après tout en assembleur
c'est bien des goto qu'on trouve ...

Patrice


"Aski" a écrit dans le message de news:

Salutatoi Jean-Marc,

Tu as donc déclaré :

"Aski" a écrit dans le message de
news:
Salutatoi Jean-Marc,

Tu as donc déclaré :

La première forme. la seconde n'apporte rien, sinon la confusion.
Note: tant que possible, on évite les Exit For (ce n'est pas un
crime de l'utiliser, mais avec parcimonie). On préfèrera dans ce
cas un DO .. LOOP ou équivalent avec condition de sortie explicite.



Je suppose que, même dans le cas de la boucle, il est préférable
d'éliminer le 'exit do' et préférer 'loop until condition'.



Hello,

Bien entendu, tu as raison. Il faut toujours préférer les sorties
explicites aux ruptures de séquences (exit ...) car cela revient à
un Goto déguisé. Pas très grave car c'est alors un saut en avant
vers une étiquette implicite, mais quand même. Rompre la linéarité
n'est (presque) jamais la meilleure solution.



Pour être complets ajoutons que le seul GoTo admis par les puristes est
celui de 'On Error GoTo'. Il s'ensuit d'ailleurs presqu'obligatoirement un
Exit Sub pour éviter la gestion d'erreur.



1 2