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

API, COM et SDKs Delphi Discussion :

Win 7 / Server 2008 R2 : Ralentissements importants des temps de traitement


Sujet :

API, COM et SDKs Delphi

  1. #1
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2005
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2005
    Messages : 46
    Par défaut Win 7 / Server 2008 R2 : Ralentissements importants des temps de traitement
    Bonjour,

    Nous développons et maintenons une application console, en Delphi7.
    Pour simplifier, cette application est architecturée autour d'un serveur TCP, qui répond aux sollicitations d'applications de type CGI pour générer des pages HTML.(génération de graphiques avec Teechart, récupération de données en DB avec DbExpress)

    Nous avons constaté sur Windows 7 et Windows Server 2008 R2 de gros ralentissements des temps de traitement de cette application (temps multipliés par 2 ou 3 par rapport à un Win XP ou un Win Server 2003) dans son contexte normal d'exécution (application lancée en "Service" avec le compte Système) .
    Lorsque que cette application est lancée par un utilisateur (depuis une console par exemple ou bien en debug dans l'EDI) il n'y a pas de problèmes de lenteur.

    Ma première question est donc, est-ce que des personnes ont rencontré/constaté des ralentissements de ce genre ?

    Ce que nous avons constaté à l'aide de ProcessExplorer, entres autres, c'est que lorsque l'application est lancée en "service" elle ne créée aucun GDI Handle ni User Handle alors que si elle est lancée par un utilisateur elle en créé quelques uns (alors que sous Win XP, quelque soit le mode de lancement, l'application à toujours accès a ce type de Handle).
    Cela peut il avoir un rapport avec notre problème ?

    Si vous avez expérimenté des comportements de ce genre, quels ont été vos contournements ?

    D'avance merci.

  2. #2
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2005
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2005
    Messages : 46
    Par défaut
    Je pense que nous avons trouvé l'origine de nos problèmes. Alors pour ceux qui chercheraient un jour, voici ce que l'on a trouvé :

    Les lenteurs seraient dues à l'utilisation de fonctions de l'API Win32 utilisant les locales. En effet, les fonctions utilisant un Locale Identifier seraient en voie d'être deprecated au profit de fonctions utilisant le Locale Name (voir http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx).

    Nos développements font appel de manière importante à CompareString (http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx), notamment avec l'utilisation de la méthode indexOf de la TStringList. C'est l'exécution de cette méthode (CompareStringA de Kernell32) qui est ralentie lors de l'exécution dans le contexte utilisateur System (en Session 0).

    En contournement, nous avons donc surchargé TStringList pour utiliser compareStr plutôt que compareString. Ce contournement nous convient dans notre contexte mais compareStr fait des comparaisons bit à bit et prend donc la casse en compte contrairement à CompareString. (Sans évoquer le fait que cette méthode est environ 10 fois plus rapide ... ce qui ne gâche rien au final : http://www.gefvert.org/blog/archives/651)

    Un autre solution serait de passer à une version plus récente de l'EDI mais ça nous savons tous que c'est une autre histoire...

  3. #3
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 933
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 933
    Par défaut
    Si la liste est longue et les traitements réguliers, n'aurais-tu pas avantage à travailler sur une table de hash ?
    Si elle est fixe ou évolue peu, sous D7, il y a la THashedStringList (IniFiles).

    Même la faire manuellement à base de tableau n'est pas très compliqué. La comparaison de chaînes (il y en aura forcément une) n'interviendrait que sur les collisions.

  4. #4
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2005
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2005
    Messages : 46
    Par défaut
    Bonjour,

    Je ne connaissais pas cet objet, j'en aurais peut être besoin un jour futur, merci pour le conseil.

    Pour le cas actuel, je penses que ca ne collerait pas trop : la plupart du temps nous travaillions sur des TStringLIst d'IDs entiers (transformés à l'aide inttostr) auxquels des Objects sont attachés. (la TIntList n'existant pas).

    J'ai récemment fait un changement structurel pour utiliser un objet "hand made" qui gère en parallèle 2 tableaux : un d'entier et un d'objet.
    Les gains en performance sont assez satisfaisants pour les accès en IndexOf.
    Mais là on s'éloigne vraiment du sujet initial ...

  5. #5
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 933
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 933
    Par défaut
    Citation Envoyé par Floverdoz Voir le message
    Mais là on s'éloigne vraiment du sujet initial ...
    C'est toi qui sait
    Mais d'après ce que tu dis, l'usage d'une TStringList ne paraît pas très logique...

    Ensuite que le calcul de hash soit fait sur une chaîne numérique ou alphabétique n'a aucune importance. Le but étant de comparer des valeurs numériques (Les hashs) et non des chaînes (caractère par caractère). Parler même de comparaison n'est pas bon puisque le hash calculé est déjà l'index dans notre tableau ! Il n'y a que les collisions à comparer. (Les collisions étant des mots différents représentés par le même hash)

    A titre d'exemple, j'avais besoin de faire de l'aide à la saisie et donc une recherche dans un dictionnaire (Plus de 200'000 mots). En calculant un hash correct (après suppression des accents et ligatures), la recherche ne prenait plus que quelques millisecondes (vraiment de l'instantané pour l'utilisateur) et la génération de la table moins d'une dizaine de secondes au démarrage du programme !

    A mon sens (et sans hash puisque c'est déjà du numérique), le but serait d'avoir un tableau de la taille de l'entier maximal et de simplement pointer sur le bon enregistrement par rapport à la valeur d'entrée. Le facteur de gain ne serait pas de 2 ou 3 (qui dépend encore de la position de la chaîne dans la liste), mais de 10'000

    A titre d'essai, tu ne risques rien à remplacer les déclarations TStringList par THashedStringList. Les méthodes sont identiques !

  6. #6
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2005
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2005
    Messages : 46
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Mais d'après ce que tu dis, l'usage d'une TStringList ne paraît pas très logique...
    Ca je suis bien d'accord c'est pour ça que je l'ai supprimée !

    Quand on arrive dans un boite, avec un code existant qui "marche" le bon vieux "on ne touche pas ce qui marche" prévaut. On se contente de faire des petits ajouts à droite, à gauche.

    Maintenant que ça ne marchait justement plus trop, j'ai pu leur tordre le cou (aux TStringLIst)

    Je vais tester par la HashedStrignList et comparer les temps par rapport à mon objet "maison". Mais les performances que tu annonces sont très alléchantes.

    Citation Envoyé par Andnotor Voir le message
    le but serait d'avoir un tableau de la taille de l'entier maximal et de simplement pointer sur le bon enregistrement
    J'y ai pensé initialement mais nous avons des Ids qui vont de 1 à plusieurs centaines de milliers, avec bien évidemment, des trous au milieu.
    Je me suis dit que ca ferait un peu trop de mémoire consommée pour rien, c'est pour ca que j'ai mis en place ce type de double tableau qui se correspondent.

  7. #7
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 933
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 933
    Par défaut
    Citation Envoyé par Floverdoz Voir le message
    J'y ai pensé initialement mais nous avons des Ids qui vont de 1 à plusieurs centaines de milliers, avec bien évidemment, des trous au milieu.
    Je me suis dit que ca ferait un peu trop de mémoire consommée pour rien, c'est pour ca que j'ai mis en place ce type de double tableau qui se correspondent.
    100'000 pointeurs vacants (nil) représentent moins de 400k en 32 bits ! Négligeable

  8. #8
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2005
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2005
    Messages : 46
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    100'000 pointeurs vacants (nil) représentent moins de 400k en 32 bits ! Négligeable
    Oui et Non.

    Oui si je n'ai qu'un seul de ses tableaux.
    Non si j'ai plusieurs milliers de ces tableaux ... Et c'est "malheureusement" mon cas. Chaque Ko compte...

    En tout cas merci de ton intérêt.

  9. #9
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 933
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 933
    Par défaut
    On ne pourra te donner plus d'informations que lorsque tu nous en diras un peux plus sur la finalité et le concept adopté

    Il est clair qu'avoir des StringList créées mais vides n'est pas sans impact !

    Dans l'exemple de recherche de mots citée précédemment, j'utilisais un tableau à 2 dimensions (les dimensions étant des tableaux dynamiques).
    L'indexe était donné par le hash calculé,
    Le premier niveau correspondait au nombre de caractères entrés,
    Le deuxième niveau aux collisions représentées par un index dans la liste de mots.

  10. #10
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2005
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2005
    Messages : 46
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    On ne pourra te donner plus d'informations que lorsque tu nous en diras un peux plus sur la finalité et le concept adopté
    Je m'en doutes bien ^^.
    Je reste volontairement vague, car ce n'est pas l'objet initial de mon poste sur developpez.

    Mon problème était que le même code exécuté sur Win7/Server2008R2 mettait beaucoup plus de temps que sur XP ou Server2003.
    Il se trouve que cela est dû aux fonctions système, de comparaison de texte, sur lesquelles sont basées la TStringList.

    J'ai résolu mon problème en utilisant d'autres fonctions / structure d'objets, qui, en plus, m'ont permis des gains de performance non négligeables.

    Je partage ma résolution car si d'autres personnes rencontrent un jour ces problèmes ça pourra les aider.
    Mais je ne cherche pas, pour le moment, d'autres structures de données. Mon application fonctionne à nouveau, et plus vite qu'avant.

    Merci beaucoup de ta participation

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 09/04/2015, 17h10
  2. [python{2.7,3.4} Amélioration des temps de traitement
    Par avi3000 dans le forum Général Python
    Réponses: 18
    Dernier message: 15/08/2014, 16h12
  3. Microsoft SQL Server 2008 Express et noms des classes ADO.NET
    Par Amine Joundy dans le forum ADO.NET
    Réponses: 3
    Dernier message: 22/12/2010, 13h41
  4. Réponses: 2
    Dernier message: 21/01/2005, 12h55
  5. Importer des données dans sql server avec DELPHI ???
    Par moutanakid dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 11/08/2004, 17h22

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