Pregunta

Tengo una unidad de prueba muy sencilla que simplemente asigna una gran cantidad de cadenas:

public class AllocationSpeedTest extends TestCase {

    public void testAllocation() throws Exception {

        for (int i = 0; i < 1000; i++) {
            long startTime = System.currentTimeMillis();
            String a = "dummy";
            for (int j = 0; j < 1000; j++) {
                a += "allocation driven";
            }
            System.out.println(i + ": " + (System.currentTimeMillis() - startTime) + "ms " + a.length());
        }

    }

}

En mi PC con Windows (Intel Core Duo, 2,2 GHz, 2 GB) esta opción se imprime en promedio:

...
71: 47ms 17005
72: 47ms 17005
73: 46ms 17005
74: 47ms 17005
75: 47ms 17005
76: 47ms 17005
77: 47ms 17005
78: 47ms 17005
79: 47ms 17005
80: 62ms 17005
81: 47ms 17005
...

En SunOS (5.10 Generic_138888-03 sun4v SPARC SUNW, SPARC Enterprise T5120-):

...
786: 227ms 17005
787: 294ms 17005
788: 300ms 17005
789: 224ms 17005
790: 260ms 17005
791: 242ms 17005
792: 263ms 17005
793: 287ms 17005
794: 219ms 17005
795: 279ms 17005
796: 278ms 17005
797: 231ms 17005
798: 291ms 17005
799: 246ms 17005
800: 327ms 17005
...

versión JDK 1.4.2_18 es en ambas máquinas. parámetros de JVM son los mismos y son:

–server –Xmx256m –Xms256m

Puede alguien explicar por qué servidor Sun súper es más lento?

( http://www.sun.com/servers/coolthreads/ T5120 / performance.xml )

¿Fue útil?

Solución

La CPU es de hecho más lento en SPARC (1,2 GHz) y como respondida por uno de los ingenieros T2 del Sol es usualy 3 veces más lenta para la aplicación de un solo subproceso que los procesadores Intel modernos. Sin embargo, también declaró que en un entorno multi-hilo SPARC debe ser más rápido.

he hecho una prueba de multi-hilo usando la biblioteca GroboUtils y probado ambas asignaciones (a través de concatenaciones) y cálculos simples (a + = j * j) para probar procesador. Y tengo los siguientes resultados:

1 thread : Intel : Calculations test : 43ms
100 threads : Intel : Calculations test : 225ms

1 thread : Intel : Allocations test : 35ms
100 threads : Intel : Allocations test : 1754ms

1 thread : SPARC : Calculations test : 197ms
100 threads : SPARC : Calculations test : 261ms

1 thread : SPARC : Allocations test : 236ms
100 threads : SPARC : Allocations test : 1517ms

SPARC muestra su poder aquí por superar a Intel en 100 hilos.

Aquí va la prueba de cálculo multi-hilo:

import java.util.ArrayList;
import java.util.List;

import net.sourceforge.groboutils.junit.v1.MultiThreadedTestRunner;
import net.sourceforge.groboutils.junit.v1.TestRunnable;
import junit.framework.TestCase;

public class TM1_CalculationSpeedTest extends TestCase {

    public void testCalculation() throws Throwable {

        List threads = new ArrayList();
        for (int i = 0; i < 100; i++) {
            threads.add(new Requester());
        }
        MultiThreadedTestRunner mttr = new MultiThreadedTestRunner((TestRunnable[]) threads.toArray(new TestRunnable[threads.size()]));
        mttr.runTestRunnables(2 * 60 * 1000);

    }

    public class Requester extends TestRunnable {

        public void runTest() throws Exception {
            long startTime = System.currentTimeMillis();
            long a = 0;
            for (int j = 0; j < 10000000; j++) {
                a += j * j;
            }
            long endTime = System.currentTimeMillis();
            System.out.println(this + ": " + (endTime - startTime) + "ms " + a);
        }

    }

}

Aquí va la prueba multi-hilo de la asignación:

import java.util.ArrayList;
import java.util.List;

import junit.framework.TestCase;
import net.sourceforge.groboutils.junit.v1.MultiThreadedTestRunner;
import net.sourceforge.groboutils.junit.v1.TestRunnable;

public class TM2_AllocationSpeedTest extends TestCase {

    public void testAllocation() throws Throwable {

        List threads = new ArrayList();
        for (int i = 0; i < 100; i++) {
            threads.add(new Requester());   
        }
        MultiThreadedTestRunner mttr = new MultiThreadedTestRunner((TestRunnable[]) threads.toArray(new TestRunnable[threads.size()]));
        mttr.runTestRunnables(2 * 60 * 1000);

    }

    public class Requester extends TestRunnable {

        public void runTest() throws Exception {
            long startTime = System.currentTimeMillis();
            String a = "dummy";
            for (int j = 0; j < 1000; j++) {
                a += "allocation driven";
            }
            long endTime = System.currentTimeMillis();
            System.out.println(this + ": " + (endTime - startTime) + "ms " + a.length());
        }

    }

}

Otros consejos

Es mi entendimiento de que las máquinas basadas en UltraSPARC T2 están dirigidos a un rendimiento por vatio en lugar de rendimiento bruto. Usted puede tratar de dividir la asignación del tiempo por el consumo de energía y ver qué tipo de números que se obtiene. :)

¿Hay alguna razón que se está ejecutando 1.4.2 en lugar de 1,6?

El hardware SunOS es más lento, y la máquina virtual puede ser algo más lento también.

No creo que esta es la medición de la asignación de memoria. Para empezar, hay una gran cantidad de copias carácter pasando en a += "allocation driven";. Pero sospecho que el verdadero cuello de botella está en conseguir la salida de System.out.println(...) a través de las capas de la red desde la aplicación en el servidor Sun a su estación de trabajo remota.

A modo de experimento, trate de multiplicar el número de bucle interno en un 10 y 100, y ver si se "acelera" el servidor Sun con respecto a su estación de trabajo.

Otra cosa que podría intentar es para mover el bucle interno en un procedimiento separado. Es posible que, dado que está haciendo todo el trabajo en una invocación de main, el compilador JIT nunca tiene la oportunidad de compilarlo.

(artificiales "micro-puntos de referencia" como este son siempre susceptibles a los efectos como los siguientes. Tiendo a desconfiar de ellos.)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top