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

Longueur d'une chaîne d'un enregistrement

2 réponses
Avatar
Aski
Bonjour,

J'utilise un tableau dynamique d'enregistrements dont le type (simplifié)
est de la forme

Private Type StringsRecord
String_1 As String
String_2 As String
End Type

J'ai 2 questions sur ce tableau :
- la longueur de chaque élément du tableau est elle égale à la somme des
longueurs des chaînes de chaque élément ou à la somme des plus grandes
longueurs de ces chaînes de l'ensemble des éléments (analogie avec les
fichiers ADR)
- est-ce que, lorsqu'une chaîne d'un enregistrement est affectée d'une
chaîne plus courte, la mémoire utilisée par le tableau diminue d'autant ?

Merci de expertise !
--
Cordialement
Aski

2 réponses

Avatar
jean-marc
"Aski" wrote in message
news:OSgx4qh%
Bonjour,



Hello,


J'utilise un tableau dynamique d'enregistrements dont le type (simplifié)
est de la forme

Private Type StringsRecord
String_1 As String
String_2 As String
End Type

J'ai 2 questions sur ce tableau :
- la longueur de chaque élément du tableau est elle égale à la somme des
longueurs des chaînes de chaque élément ou à la somme des plus grandes
longueurs de ces chaînes de l'ensemble des éléments (analogie avec les
fichiers ADR)



La taille de chaque élément est une fonction de la somme des longueurs des
chaines de chaque élément. "Est une fonction" et non pas "est égale", car il
y a de l'overhead. Par exemple pour un tableau de 100.000 elements, si tu
fais juste

Dim t() as StringsRecord

redim t(100000)

=> Hop, ici tu consommes 800 Ko

En effet, une chaine (vide) occupe 4 bytes.
Tu as 2 string par record donc 4*2 = 8 bytes
8 bytes * 100000 = 800000 = 800 Ko, le compte est bon!

Puis quend tu affectes des caractères, la "taille" des records est une
fonction linéaire du nombre de caractères (pas une égalité).

- est-ce que, lorsqu'une chaîne d'un enregistrement est affectée d'une
chaîne plus courte, la mémoire utilisée par le tableau diminue d'autant ?



Et non, hélas!
Voici pourquoi: les chaines en VB sont stockés sous la forme:
+--------+----------------+
|longueur|caracteres ... |
+--------+----------------+

Quand tu affectes une chaine de longueur 10, VB stocke la longueur dans les
premiers bytes, alloue de la mémoire pour 10 caractères (et ce n'est PAS 10
bytes...) et stocke les caractères.

Puis si tu affectes une chaine de 20, VB réalloue de la place pour 20,
stocke les 20, et libère l'ancienne place pour les 10 (ce qui est
affreusement lent, voir la suite).

MAIS: si maintenant tu réaffectes une chaine de 5 caractères, VB va placer
les 5 caractères, ET AJUSTER la longueur. ET c'est tout. Il ne libère pas la
place précédemment allouée (pour des raisons évidentes de performances).

Ceci explique pourquoi notamment la concaténation naïve est si lente et
pourquoi il faut utiliser des techniques un peu "sioux" pour concaténer
rapidement.
A ce propos (habile digression...), voir le nouvel article de la FAQ
consacré au sujet:
http://faq.vb.free.fr/index.php?question3

Merci de expertise !




Cordialement aussi :-)


--
Jean-marc Noury (jean_marc_n2)
Microsoft MVP - Visual Basic
FAQ VB: http://faq.vb.free.fr/
mailto: remove '_no_spam_' ;
Avatar
Aski
Hello jean-marc,

En effet, une chaine (vide) occupe 4 bytes.
Tu as 2 string par record donc 4*2 = 8 bytes
8 bytes * 100000 = 800000 = 800 Ko, le compte est bon!



Compris :o)
Cela me fait penser aux enregistrements du Pascal.

MAIS: si maintenant tu réaffectes une chaine de 5 caractères, VB va
placer les 5 caractères, ET AJUSTER la longueur. ET c'est tout. Il ne
libère pas la place précédemment allouée (pour des raisons évidentes
de performances).



C'est bien ce que je craignais, il me faut donc réduire les chaînes avant de
les placer dans le tableau.

A ce propos (habile digression...), voir le nouvel article de la FAQ
consacré au sujet:
http://faq.vb.free.fr/index.php?question3



J'avais suivi le fil. Merci
--
B ien cordialement
Henri