Bonnes pratiques de l'utilisation du Storage

Y a t’il des techniques à utiliser dans le code pour optimiser au maximum les appels au Storage ?

Faut il passer par des variables locales ? si oui quoi ?

Pourquoi poses-tu cette question ?

Parce que j’utilise de plus en plus le Storage et que je ne suis pas encore un spécialiste sur ce domaine et que j’aimerai bien connaitre la(les) bonne(s) façon(s) de l’utiliser au mieux niveau optimisation lors de l’écriture de mon code.

par exemple ce bout de code :
<code 4D>
OBJET FIXER COULEURS RVB(*;$Obj_T;Coul premier plan;Num(Storage.TB_Interface.Couleur_Pyjama_Impaire);Num(Storage.TB_Interface.Couleur_Pyjama_Paire))

</code 4D>

serait-il mieux écrit (optimisé) en passant Storage.TB_Interface dans une locale pour n’avoir qu’un seul appel au Storage :?:

Suite à une réponse faite http://forums.4d.com/Post/FR/30962566/2/31219766#31048876à un autre post> (sans rapport) VDL rappelait le coût d’accès au storage. Ensuite je n’en sais pas plus sur ce coût.

Tout comme toi, j’avais bien lu et compris ce coût supplémentaire ET c’est bien pour cela que j’aimerais connaître la meilleure façon d’écrire mon code pour le réduire au maximum.

Dans mon exemple la ligne provoque t’elle 2 appels au Storage ? si oui peut-être qu’en passant par un variable locale cela ne ferait plus qu’un seul appel par exemple. :doubt:

Bonjour,

Je pense que le coût le plus important est lors de l’écriture dans le Storage et que le coût de la lecture est moindre.
De ce que je pense avoir compris, c’est que le Storage n’est pas là pour être un lieu de mémoire tampon, mais peut être utilisé pour stocker des choses qui ne varient que très peu voire pas du tout.

Je ne remets pas en cause le contenu du Storage, ce qui m’intéresse c’est la meilleure façon de l’utiliser dans le code. Une fois qu’on a pris la décision de placer une chose dans le Storage comment on l’utilise au mieux.

Je dirai que tu y accèdes comme une variable : tu lis l’information quand tu en as besoin :wink:

Maintenant, si je devais accéder plusieurs fois à la même info au sein de la même méthode, je pense que je passerai par une variable temporaire intermédiaire afin d’éviter de faire appel au Storage plusieurs fois.
=> si je peux limiter l’accès, je le fais.

Quel gain par rapport à une variable locale en terme d’accès et de vitesse, aucune idée.

Dans ton exemple, tu ne fais qu’un appel au storage sans passer par un Utiliser/Fin utiliser (obligatoire en écriture, facultatif en lecture), donc sans bloquer l’accès à Storage, voir ce que ce blocage change https://forums.4d.com/Post/FR/27453614/2/27472825#27472825ici>. Copier dans une locale ne fera que prendre un chouia plus de temps…

Si tu devais faire des lecture répétées du storage (en boucle), je suppose que tu te demandes si tu gagnes du temps à ne faire qu’une lecture du storage dans une locale vs et à boucler sur cette locale, un truc du genre :
<code 4D>
TABLEAU ENTIER LONG($count_al;2)
C_OBJET($userInfo_o;$storage_o)

$i_l:=1  //lectures répétées de Storage
$end_l:=Nombre de ticks+60
Repeter
	$count_al{$i_l}:=$count_al{$i_l}+1
	$userInfo_o:=Storage.user
Jusque (Nombre de ticks>$end_l)

$i_l:=2  //une seule lecture de Storage
$end_l:=Nombre de ticks+60
$storage_o:=Storage
Repeter
	$count_al{$i_l}:=$count_al{$i_l}+1
	$userInfo_o:=$storage_o.user
Jusque (Nombre de ticks>$end_l)

</code 4D>
et là, je constate que je ne gagne toujours rien. Donc, quand on ne fait que lire Storage, il semblerait que ça n’a pas grand intérêt de copier dans une locale.

Sans les resultats chiffrés, je ne vois pas grand chose :razz:

Par contre, en relisant ce que tu dis cela peut avoir quand même un interet de passer par une locale de cette façon :

<code 4D>
C_OBJET($storage_o)
$storage_o:=Storage.TB_Interface

</code 4D>

et plus loin dans le code d’utiliser cela comme cela :

<code 4D>
OBJET FIXER COULEURS RVB(*;$Obj_T;Coul premier plan;Num($storage_o.Couleur_Pyjama_Impaire);Num($storage_o.Couleur_Pyjama_Paire))

</code 4D>

car cela ne bloque pas le Storage, certes, mais cela permet de conserver la pertinence des informations lues (en même temps !) bon ici pas problématique mais dans des cas d’infos qui ont besoin d’unicité en lecture (adresse mail et son mot de passe, adresse postale, etc…) cela peut avoir un intérêt plutôt que d’encadrer tout ton code avec un Utiliser/Fin utiliser non ?

J’ai des lignes comme ça :

<code 4D>
C_TEXT($T_URL;$T_User_agent;$T_AppID)
$T_User_agent:=Application detail storage .nom_application+" “+Application detail storage .version_application+” "+String(Application detail storage .build_application)
$T_URL:=Storage_tablette .url
$T_AppID:=Storage_tablette .appuuid

</code 4D>

Storage_tablette est une méthode

J’ai pas tout suivi ?:oops:
C’est quoi ce nom pourri avec des espaces dedans ? :mrgreen:

et dans ton code rien n’empêcherait de lire une url qui ne serait pas en accord avec to appuuid

il serait préférable de faire :

<code 4D>
C_TEXT($T_URL;$T_User_agent;$T_AppID)
C_OBJET($Storage_o)
$Storage_o:=Storage_tablette
$T_URL:=$Storage_o.url
$T_AppID:=$Storage_o.appuuid

</code 4D>

: Manuel PIQUET

Sans les resultats chiffrés, je ne vois pas grand chose :razz:
si je te file le code, c’est pour que tu te fasses chier pour rien comme moi :mrgreen:
Plus concrètement, nbre de lectures = 131K contre 138K, soit 6% de lectures en plus via la copie, pas de quoi s’affoler. Pas testé en compilé, mais je doute que ça change quoi que ce soit.

: Manuel PIQUET

Par contre, en relisant ce que tu dis cela peut avoir quand même un
interet de passer par une locale de cette façon
Je n’en ai pas parlé car dans ton exemple original, je voyais le truc à lire dans storage comme “figé” - le temps de la session. Mais, effectivement, si ce que tu y lis peut être modifié par un autre process n’importe quand, ça t’oblige à protéger par un Utiliser ; auquel cas ton premier bout de code devrait être :
<code 4D>
utiliser(Storage) //je verrouille le temps de lire
C_OBJET($storage_o)
$storage_o:=Storage.TB_Interface
fin utiliser //j’ai fini de lire, je m’en fiche si c’est modifié ultérieurement
</code 4D>
En même temps, je ne vois pas trop dans quelle situation je devrais lire un truc qui peut bouger n’importe quand. Je risque plus d’avoir à lire un truc qui a été positionné le temps que je le lise, genre poster message…relever message.

PS : j’ai voulu faire un effort de lisibilité après coup, mais l’éditeur du forum est mauvais sur Utiliser/Fin utiliser.

: Manuel PIQUET

C’est quoi ce nom pourri avec des espaces dedans ?

J’ai rien compris de ton explication :mrgreen:

Mon code ou ton code : كيف كيف kifkif

@Bertrand

Si tu lis des infos dans le Storage qui peuvent être modifiées et qui n’ont de sens que par pair comme une adresse mail et son mot de passe. il faut sécurisé la lecture en une seule requête sinon tu risques une désynchronisation de l’info càd. avoir une adresse mail et un mot de passe qui ne correspond pas ou plus par exemple.

Du coup, Arnaud si on lit un objet en entier y a t’il un risque de cette nature ?

<code 4D>
C_OBJET($storage_o)
$storage_o:=Storage.TB_Interface
</code 4D>

ça peut pas lire un objet avec des propriétés pourries si ?

est-il equivalent à :

<code 4D>
utiliser(Storage)//je verrouille le temps de lire
C_OBJET($storage_o)
$storage_o:=Storage.TB_Interface
fin utiliser//j’ai fini de lire, je m’en fiche si c’est modifié ultérieurement

</code 4D>

:?:

si on lit un objet en entier y a t’il un risque de cette nature ?
J’imagine qu’un objet doit être une adresse mémoire qui elle-même en référence d’autres (gigognes).

Un objet étant écrit comme ça :
zeObj.machin.bidule:=“bla bla”
zeObj.machin.truc:=1234
… rien ne permet de prétendre qu’il ne va rien se passer entre ce deux lignes, bidule peut avoir été modifié quand j’écris truc.

À la lecture, je ne pense pas qu’il en aille autrement.

Enfin, sauf à faire des tests bien pénibles pour prouver le contraire, je ne prendrais pas ce risque, alors qu’avec le Utiliser je suis certain de lire “en entier”.