2010-03-28 12 views
5

Greets-de Java a reducir el uso de CPU

Nos gots unos locos en el trabajo que disfrutan usando

while(true) { //Code } 

en su código. Como se puede imaginar, esto maximiza la CPU. ¿Alguien sabe cómo reducir la utilización de la CPU para que otras personas puedan usar el servidor también?

El código en sí mismo consiste en sondear constantemente en Internet las actualizaciones de los sitios. Por lo tanto, me imagino que un pequeño método para dormir reduciría en gran medida el uso de la CPU.

Además, toda la manipulación se realiza en objetos String (Java), ¿alguien sabe cuánto reduciría la producción de StringBuilders por encima?

Gracias por cualquier punteros

+4

'while (true)' es simplemente un modismo que dice "haz esto para siempre". Por sí mismo, no hace nada; el código dentro de él es lo que consume ciclos de CPU. Si el código interno está haciendo solicitudes de red, abandonará su división de tiempo al hacerlo, para que otros usuarios obtengan las suyas; un '' sleep() 'no debería afectar significativamente el rendimiento general del servidor (aunque sería una buena cosa para los servidores que reciben el programa). Y finalmente, 'StringBuilder' puede o (más probable) puede no mejorar el rendimiento. Pero es por eso que los profilers existen: pueden decirle qué es lo que más tiempo le toma al programa. – kdgregory

+3

Como siempre, ejecute un generador de perfiles para identificar dónde va la CPU. Luego usa esa información para vencer al desarrollador responsable en la cabeza. –

+0

¿Qué sistema operativo? –

Respuesta

6

Voy a empezar con la segunda pregunta, me gustaría llegar a un acuerdo con el resto que StringBuilder vs cuerdas es muy dependiente de las manipulaciones de cadenas particulares. Había "evaluado" esto una vez y, en general, a medida que aumentaba la cantidad de nuevas asignaciones de cadenas (generalmente en forma de concatenaciones), el tiempo de ejecución general aumentaba. No entraré en detalles y solo diré que StringBuilder resultó ser el tiempo extra más eficiente, en comparación con String, StringBuffer, String.format(), MessageFormat ...

Mi regla de oro es que siempre que deseo concatenar más de 3 cadenas juntas. Siempre uso StringBuilder.

En cuanto a su primera pregunta. Teníamos el requisito de llevar el uso de la CPU al 5%. No es una tarea fácil. Usamos el mecanismo de AOP de Spring para agregar un Thread.sleep() a cualquier método de ejecución de un método intensivo de CPU. El Thread.sleep() se invocará solo si se ha excedido algún límite. Lamento decir que el cálculo de este límite no es tan simple. Y más aún decir que aún no obtuve el permiso para publicarlo en la red. Así que esto es solo para ponerlo en una pista interesante pero complicada que ha demostrado funcionar con el tiempo.

+2

¿Qué posible razonamiento podría llevar a un requisito de "no más de 5% de tiempo de CPU"? Si tiene una tarea intensiva de CPU, entonces tiene una tarea intensiva de CPU. No hay forma de evitarlo, y agregar duerme a tu código simplemente hace que la tarea tarde más. Si le preocupa el impacto de un programa en particular en los recursos generales del sistema, entonces es mucho más inteligente simplemente reducir la prioridad de ese programa. O compra otra computadora. – kdgregory

+1

Personalmente, ¡no podría estar más de acuerdo con usted! Sin embargo, no soy más que un simple programador y no "diseñé" esta solución. Mi único punto era que este tipo de cosas PODRÍA hacerse, si fuera necesario :) – Yaneeve

+0

@Yaneeve ... Demasiado tarde para preguntar esto. ¿Cómo manejó la compensación entre la velocidad y el uso de la CPU? Estoy seguro de que el sueño tuvo un impacto en el rendimiento ya que aumentó el tiempo de ejecución. – bluelurker

2

Hacer que esperar algún tiempo antes de disparar de nuevo, como esto:

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

En cuanto a la segunda pregunta, se reduciría la memoria y, posiblemente, el uso de CPU, así, pero el las ganancias realmente dependen de lo que está sucediendo con esas cadenas.

4

¿Con qué frecuencia se actualizan esos sitios? Probablemente estés molestando a los anfitriones. Solo inserte un Thread.sleep(60 * 1000); al final del ciclo y puede evitar esto. Eso los va a sondear una vez por minuto. ¿Seguro que es suficiente?

2

Un reposo reduciría el uso de la CPU. En cuanto a los StringBuilders, podrían reducir el uso de la memoria y mejorar el rendimiento.

0

También puede probar

Thread.yield() 
+3

@Helper Method - "Rendimiento" solo hace que el objeto de ejecución actualmente en ejecución temporalmente pause y permita que se ejecuten otros subprocesos ... por lo que esto solo reducirá significativamente el uso de la CPU si hay otras aplicaciones de usuario ejecutándose en paralelo. "Dormir" será más adecuado a lo que quiere lograr. – XpiritO

+0

@XpritO Sry, tienes razón. No entendí el punto del OP.Tal vez no debería leer la publicación antes de mi segundo café ^^. – helpermethod

+0

esa es la razón en el 5% de la carga de la CPU, para darle a otras aplicaciones espacio para 'respirar' en la misma computadora, y eso se puede lograr colocando algo de Thread.yield() en lugares críticos del código. Estoy haciendo eso y es muy útil desde el punto de experiencia de uso de software normal. –

7

Mucha de la "sabiduría popular" sobre StringBuilder es incorrecta.Por ejemplo, el cambio de esto:

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

a esto:

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

probablemente no va a hacer que vaya más rápido. Esto se debe a que el compilador de Java realmente traduce la secuencia de concatenación en una secuencia equivalente de anexa a un StringBuilder temporal. A menos que esté concatenando cadenas en un bucle, es mejor que solo use el operador +. Tu código será más fácil de leer.

El otro punto que debe hacerse es que debe usar un generador de perfiles para identificar los lugares en su código que se beneficiarían del trabajo para mejorar el rendimiento. La intuición de la mayoría de los desarrolladores sobre lo que vale la pena optimizar no es tan confiable.

0

Si el código está en una JVM independiente y se ejecuta en Linux o algún otro Unix, les obligan a ejecutar su programa en buen 20.

o usted podría hacer que se ejecuten dentro de una máquina virtual como VirtualBox y uso para limitar la utilización del procesador.

O podría dispararlos si continúan los ciclos de grabación de esa manera en lugar de usar algún modelo basado en eventos o Thread.sleep.

0
  1. ¿Qué sitios de votación es el código? ¿ soportan un push de RSS?
  2. Si lo hacen, entonces no hay necesidad de sondear los sitios, y en su lugar conectar un módulo para esperar actualizaciones. El método actual luego espera usando wait();
  3. El nuevo módulo luego notifica al objeto con este método usando notifyAll().
  4. Es cierto que esto es un trabajo extra, pero ahorra mucho ancho de banda y computación.
Cuestiones relacionadas