IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Conseils sur le stockage de nombreuses chaines de caractères (+ de 2000 chaines de taille ~128-256)


Sujet :

C#

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 15
    Points : 23
    Points
    23
    Par défaut Conseils sur le stockage de nombreuses chaines de caractères (+ de 2000 chaines de taille ~128-256)
    Bonjour, je développe un serveur de jeu sur un jeu existant dont la plateforme multijoueur utilise une api en c#. Dans ce projet, le client va souvent recevoir des messages sur son écran, et, étant débutant sur c#, je me retrouve face à un problème d'organisation quant au stockage de ces chaines de caractères.

    Mon ancien serveur de jeu était sur un autre jeu qui utilisait un langage de programmation beaucoup plus rustre, avec très peu de possibilités, de plugins, de bibliothèques. Je stockais mes messages dans un include et je définissais chaque message avec un define, cela me permettait d'avoir une étiquette pour chaque message et de les utiliser ensuite dans mes autres includes, le but n'était pas forcément de pouvoir les recenser au meme endroit mais surtout de raccourcir mon code quand j'utilisais une instruction d'envoi d'un message, de facon à ce que ce soit beaucoup plus lisible. Je sais, c'est très barbare et surement pas recommandable du tout mais ce langage était vraiment archaique et ca marchait très bien au final.


    Etant maintenant sur ce nouveau projet en c#, je doute qu'utiliser des define pour ca soit une bonne idée. Mon but est de réunir tout les messages qui seront utilisés dans d'autres fichiers, dans un seul, et, si possible, de n'allouer aucun espace de stockage dans la mémoire du programme (un peu pour ca que j'avais utilisé des define sur cet autre langage, ca me servait pour la lisibilité dans mon code, et après la compil on en parlait plus).

    On m'a conseillé de créer une classe et d'y mettre tout les messages que j'utiliserais en static const. Je reste septique, ca me fait allouer de la mémoire pour ca ce n'est pas vraiment ce que je recherche. On m'a aussi conseillé de stocker mes messages dans un fichier xml. Je n'ai jamais utilisé xml, je ne sais pas si c'est rapide, mon but et de faire le moins de calcul possible et que ce soit très rapide.

    Etant très loin d'etre un professionnel, je vous demande votre avis quant à mon probleme, merci beaucoup.

  2. #2
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Points : 9 743
    Points
    9 743
    Billets dans le blog
    3
    Par défaut
    Plusieurs solutions s'offrent a toi :
    1. Le fichier XML: comme tu y as deja pense, ca peut etre pas mal, par contre ca necessite des acces disque (I/O). Tu peux decider soit de garder le fichier en memoire et le parcourir lorsque necessaire ; ou bien ne pas le garder en memoire et le lire a chaque fois que tu en as besoin (attention au cout des I/O dans ce cas...). L'avantage du XML c'est que tu peux le convertir en Classe C# (deserialisation)...
    2. Un fichier Ressources (.resx): Un peu similaire au fichier XML, mais avec des mecanismes integres au framework .NET. Un des avantages c'est que ca te permet d'internationaliser ton application assez facilement (avoir les messages dans differentes langues). C'est aussi "strongly typed" donc tu n'as pas besoin de caster les infos. Enfin un autre avantage est que tu peux les compiler dans un assembly independent, ce qui peut te permettre de faire des mises a jour et de deployer facilement les changements.
    3. Une base de donnees: c'est peut-etre l'artillerie lourde pour ton cas, mais ca reste une option. Le principal avantage c'est que pour les mises a jour, il te suffit de mettre a jour la DB, et au niveau performances ca reste moins couteux qu'un fichier XML .
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

  3. #3
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 541
    Points
    10 541
    Billets dans le blog
    21
    Par défaut
    Etant maintenant sur ce nouveau projet en c#, je doute qu'utiliser des define pour ca soit une bonne idée. Mon but est de réunir tout les messages qui seront utilisés dans d'autres fichiers, dans un seul, et, si possible, de n'allouer aucun espace de stockage dans la mémoire du programme (un peu pour ca que j'avais utilisé des define sur cet autre langage, ca me servait pour la lisibilité dans mon code, et après la compil on en parlait plus).
    Sauf qu'ici tu te trompes sur un point : de l'espace de stockage est utilisé au sein de ton programme, même si tu utilises des define, ne serait-ce que pour avoir les caractères constituant ta chaîne de caractères.

    Par rapport au cadre que tu décris, je privilégierai soit l'utilisation d'un fichier ressource (point 2 évoqué par DotNetMatt), soit la création d'une classe statique avec toutes tes chaînes de caractères accessible en public const. Ainsi, tu sauras à la compilation si une chaîne à laquelle tu fais références existe ou non, et tu pourras également bénéficier de la complétion dans ton IDE. Ces derniers points ne sont pas vrais si tu utilises une base de données ou un fichier XML.

    D'autant plus que tu sembles rechercher de la performance. L'accès à une base de données ou à un fichier XML a un coût, à la fois en processeur et en mémoire.

    On m'a conseillé de créer une classe et d'y mettre tout les messages que j'utiliserais en static const. Je reste septique, ca me fait allouer de la mémoire pour ca ce n'est pas vraiment ce que je recherche.
    Comme je te le disais plus haut, l'allocation mémoire était aussi présente auparavant. Maintenant, sache aussi une chose. En .Net (et donc en C#), une string est immutable, c'est-à-dire qu'une chaîne de caractères ne peut pas être modifiée. Toute opération de modification sur une chaîne de caractère en alloue une nouvelle. Un des avantages lié à cette immutabilité, c'est que si tu as une même chaîne de caractères présentes 50 fois au sein de ton code, alors tu n'auras en réalité qu'une seule instance en mémoire.
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  4. #4
    Membre expert Avatar de jopopmk
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    1 856
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 1 856
    Points : 3 570
    Points
    3 570
    Par défaut
    Salut,

    à 2 octets par char, pour 2048 strings de 256 ça fait 1Mo, c'est pas non plus la fin du monde.

    Dans l'absolu je choisirai la solution 2 de DotNetMatt : propre, encadrée par le framework, évolutive. Mais pour un si faible volume la solution de dorinf (classe statique) pourrait être la plus simple d'utilisation (tu peux même faire des sous classes statiques pour compartimenter/catégoriser tes constantes).
    Plus je connais de langages, plus j'aime le C.

  5. #5
    Membre chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    Par défaut
    Citation Envoyé par dorinf Voir le message
    Un des avantages lié à cette immutabilité, c'est que si tu as une même chaîne de caractères présentes 50 fois au sein de ton code, alors tu n'auras en réalité qu'une seule instance en mémoire.
    Attention ceci n'est valable que si "l'interning" (internement en VF ? ) des chaines est actif (ce qui est quasiment le cas tout le temps je le concède)
    Les 2 seuls cas que je connais où ça peut être différent sont en cas d'utilisation de [assembly:CompilationRelaxationsAttribute(CompilationRelaxations.NoStringInterning)] ou avec Ngen.
    Nous sommes tous plus ou moins geek : ce qui est inutile nous est parfaitement indispensable ( © Celira )
    À quelle heure dormez-vous ?
    Censément, quelqu'un de sensé est censé s'exprimer sensément.

  6. #6
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 15
    Points : 23
    Points
    23
    Par défaut
    Merci à tous pour les réponses apportées :

    Citation Envoyé par dorinf Voir le message
    Sauf qu'ici tu te trompes sur un point : de l'espace de stockage est utilisé au sein de ton programme, même si tu utilises des define, ne serait-ce que pour avoir les caractères constituant ta chaîne de caractères.

    Par rapport au cadre que tu décris, je privilégierai soit l'utilisation d'un fichier ressource (point 2 évoqué par DotNetMatt), soit la création d'une classe statique avec toutes tes chaînes de caractères accessible en public const. Ainsi, tu sauras à la compilation si une chaîne à laquelle tu fais références existe ou non, et tu pourras également bénéficier de la complétion dans ton IDE. Ces derniers points ne sont pas vrais si tu utilises une base de données ou un fichier XML.

    D'autant plus que tu sembles rechercher de la performance. L'accès à une base de données ou à un fichier XML a un coût, à la fois en processeur et en mémoire.



    Comme je te le disais plus haut, l'allocation mémoire était aussi présente auparavant. Maintenant, sache aussi une chose. En .Net (et donc en C#), une string est immutable, c'est-à-dire qu'une chaîne de caractères ne peut pas être modifiée. Toute opération de modification sur une chaîne de caractère en alloue une nouvelle. Un des avantages lié à cette immutabilité, c'est que si tu as une même chaîne de caractères présentes 50 fois au sein de ton code, alors tu n'auras en réalité qu'une seule instance en mémoire.
    Merci pour les précisions apportées, effectivement la solution base de données, je ne vais pas opter pour, d'autant que j'aurais déja pas mal d'échanges server / bdd pour d'autres type de données, du coup je tiens à éviter des requêtes pour si peu, pas rentable au vu de la valeur que j'accorde à ces données.

    Citation Envoyé par jopopmk Voir le message
    Salut,

    à 2 octets par char, pour 2048 strings de 256 ça fait 1Mo, c'est pas non plus la fin du monde.

    Dans l'absolu je choisirai la solution 2 de DotNetMatt : propre, encadrée par le framework, évolutive. Mais pour un si faible volume la solution de dorinf (classe statique) pourrait être la plus simple d'utilisation (tu peux même faire des sous classes statiques pour compartimenter/catégoriser tes constantes).
    C'est vrai que ce n'est pas la fin du monde. Je vais surement opter pour la solution numéro 2 de DottMatt, le resx, rien que pour le support multilingue et les autres arguments ca me semble très intéressant pour mes objectifs. Encore merci pour ces réponses ca m'a aidé à y voir bien plus clair.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 15
    Dernier message: 22/08/2012, 20h11
  2. Conseil sur le stockage de données
    Par zpico dans le forum Débuter avec Java
    Réponses: 1
    Dernier message: 15/04/2012, 15h31
  3. Réponses: 10
    Dernier message: 31/12/2006, 12h35
  4. Réponses: 4
    Dernier message: 07/12/2006, 11h01
  5. Supprimer le premier caractère d'une chaine de caractères
    Par Droïde Système7 dans le forum Langage
    Réponses: 2
    Dernier message: 30/09/2005, 11h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo