2010-03-28 6 views
5

Greets-Java réduire l'utilisation du processeur

Nous gots quelques cinglés dans le travail qui aiment utiliser

while(true) { //Code } 

dans leur code. Comme vous pouvez l'imaginer, cela maximise le processeur. Est-ce que quelqu'un sait comment réduire l'utilisation du processeur afin que d'autres personnes puissent également utiliser le serveur.

Le code lui-même ne fait qu'interroger constamment sur Internet les mises à jour sur les sites. Par conséquent, j'imagine qu'une petite méthode de sommeil réduirait considérablement l'utilisation du processeur.

Aussi toute la manipulation est en cours dans les objets String (Java) quelqu'un sait combien de StringBuilders réduirait l'overhead par?

Merci pour tous les pointeurs

+4

'while (true)' est simplement un idiome qui dit «fais ceci pour toujours». En soi, cela ne fait rien; le code qui s'y trouve est ce qui consomme les cycles du processeur. Si le code à l'intérieur fait des demandes de réseau, alors il abandonnera son timelice en faisant ainsi, ainsi d'autres utilisateurs obtiendront le leur; un 'sleep()' ne devrait pas affecter de façon significative le débit global du serveur (bien que ce soit une bonne chose pour les serveurs qui sont touchés par le programme). Enfin, 'StringBuilder' peut (ou plus probablement) ne pas améliorer les performances. Mais c'est pourquoi les profileurs existent: ils peuvent vous dire ce qui prend le plus de temps dans le programme. – kdgregory

+3

Comme toujours, exécutez un profileur pour identifier l'emplacement du processeur. Ensuite, utilisez ces données pour battre le développeur responsable sur la tête. –

+0

Quel système d'exploitation? –

Répondre

6

Je vais commencer par votre deuxième question, je voudrais être d'accord avec le reste que StringBuilder vs chaîne est très dépendante des manipulations de chaînes particulières. Je l'avais "comparé" une fois et de manière générale, à mesure que le montant des nouvelles attributions de chaînes augmentait (généralement sous la forme de concaténations), le temps d'exécution global augmentait. Je ne vais pas entrer dans les détails et juste dire que StringBuilder s'est avéré être le plus efficace des heures supplémentaires, par rapport à String, StringBuffer, String.format(), MessageFormat ...

Ma règle de base est que chaque fois que je souhaite concaténer plus de 3 cordes ensemble, j'utilise toujours StringBuilder.

Comme pour votre première question. Nous avions l'obligation d'amener l'utilisation du CPU à 5%. Pas une tâche facile. Nous avons utilisé le mécanisme AOP de Spring pour ajouter Thread.sleep() avant toute exécution de méthode d'une méthode intensive du processeur. Thread.sleep() ne serait invoqué que si certaines limites avaient été dépassées. Je suis désolé de dire que le calcul de cette limite n'est pas si simple. Et encore plus triste de dire que je n'ai toujours pas obtenu la permission de l'afficher sur le net. Donc, c'est juste pour vous mettre sur une piste intéressante mais compliquée qui a fait ses preuves au fil du temps.

+2

Quel raisonnement possible pourrait conduire à une exigence de "pas plus de 5% du temps CPU"? Si vous avez une tâche gourmande en ressources processeur, vous avez une tâche gourmande en ressources processeur. Il n'y a aucun moyen de contourner cela, et l'ajout de sommeil à votre code rend simplement cette tâche plus longue. Si vous êtes préoccupé par l'impact d'un programme particulier sur les ressources système globales, il est beaucoup plus intelligent de simplement réduire la priorité de ce programme. Ou acheter un autre ordinateur. – kdgregory

+1

Personnellement, je ne pourrais pas être plus d'accord avec vous! Pourtant, je ne suis qu'un simple programmeur et je n'ai pas «conçu» cette solution. Mon seul point était que ce type de chose pourrait être fait, si besoin est :) – Yaneeve

+0

@Yaneeve .. Trop tard pour demander cela. Comment avez-vous géré le compromis entre la vitesse et l'utilisation du processeur? Je suis sûr que le sommeil a eu un impact sur les performances car il a augmenté le temps d'exécution. – bluelurker

2

Faites-en attendre un certain temps avant de tirer à nouveau, comme ceci:

while(true) { 
    //Code 
    Thread.sleep (1000); //Wait 1 second 
} 

Quant à la deuxième question, il réduirait la mémoire et peut-être l'utilisation du processeur ainsi, mais le les gains dépendent vraiment de ce qui se passe avec ces chaînes.

4

À quelle fréquence ces sites sont-ils mis à jour? Vous êtes probablement vraiment ennuyant les hôtes. Il suffit de coller un Thread.sleep(60 * 1000); à la fin de la boucle et vous pouvez éviter cela. Cela les interrogera une fois par minute - c'est suffisant?

2

Une veille réduirait l'utilisation du processeur. Quant aux StringBuilders, ils pourraient réduire l'utilisation de la mémoire et améliorer les performances.

0

Vous pouvez également essayer

Thread.yield() 
+3

@Helper Méthode - « rendement » ne provoque que l'objet thread en cours d'exécution temporairement mettre en pause et permettre à d'autres threads de s'exécuter ... donc cela ne réduira l'utilisation du CPU de manière significative que s'il y a d'autres applications utilisateur fonctionnant en parallèle. "Dormir" sera plus adapté à ce qu'il veut accomplir. – XpiritO

+0

@XpritO Sry, vous avez raison. N'a pas tout à fait le point de l'OP.Peut-être que je ne devrais pas lire le post avant mon 2ème café ^^. – helpermethod

+0

C'est la raison pour laquelle 5% de la charge CPU est utilisée, pour donner aux autres applications un espace pour «respirer» sur le même ordinateur, et cela peut être réalisé en mettant du Thread.yield() dans des endroits critiques du code. Je le fais et il est très utile à partir du point de l'expérience d'utilisation normale du logiciel .. –

7

Une grande partie de la «sagesse populaire» sur StringBuilder est incorrecte.Par exemple, changer ceci:

String s = s1 + ":" + s2 + ":" + s3; 

à ceci:

StringBuilder sb = new StringBuilder(s1); 
sb.append(":"); 
sb.append(s2); 
sb.append(":"); 
sb.append(s3); 
String s = sb.toString(); 

probablement ne le fera pas aller plus vite. Cela est dû au fait que le compilateur Java traduit réellement la séquence de concaténation en une séquence équivalente d'ajouts à un StringBuilder temporaire. Si vous ne concaténéz pas les chaînes dans une boucle, il vaut mieux utiliser l'opérateur +. Votre code sera plus facile à lire.

L'autre point qui devrait être fait est que vous devriez utiliser un profileur pour identifier les endroits dans votre code qui pourraient bénéficier d'un travail pour améliorer les performances. L'intuition de la plupart des développeurs sur ce qui vaut la peine d'être optimisé n'est pas si fiable.

0

Si leur code est dans une machine virtuelle Java séparée et est en cours d'exécution sous Linux ou autre Unix, les obliger à exécuter leur programme à nice 20.

Ou vous pourriez les exécuter dans une machine virtuelle comme VirtualBox et l'utilisation pour limiter l'utilisation du processeur.

Ou vous pouvez les déclencher s'ils continuent à graver des cycles comme cela au lieu d'utiliser un modèle piloté par événement ou Thread.sleep.

0
  1. Quels sites est le vote de code? Est-ce que supporte un push RSS?
  2. Si tel est le cas, il n'est pas nécessaire de interroger les sites et de brancher un module pour attendre les mises à jour. La méthode en cours attend alors en utilisant wait();
  3. Le nouveau module notifie alors l'objet avec cette méthode en utilisant notifyAll().
  4. Certes, c'est un travail supplémentaire, mais cela économise beaucoup de bande passante et de calcul.