Frage

Ich habe einen sehr einfachen Unit-Test, dass nur eine Menge von Strings reserviert:

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());
        }

    }

}

Auf meinem Windows-PC (Intel Core Duo, 2,2 GHz, 2 GB) diesen Druck im Durchschnitt:

...
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
...

Auf 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
...

JDK Version 1.4.2_18 auf beiden Maschinen. JVM Parameter sind die gleichen und sind:

–server –Xmx256m –Xms256m

erklären kann, warum jemand SUN Super-Server langsamer ist?

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

War es hilfreich?

Lösung

Die CPU ist in der Tat langsamer auf SPARC (1,2 GHz) und als von einem der Ingenieure von Sun beantwortete T2 ist usualy 3 mal langsamer für Single-Threaded-Anwendung als moderne Intel-Prozessoren. Obwohl er auch, dass SPARC sollte schneller sein in einer Multi-Threaded-Umgebung angegeben.

Ich habe einen Multi-Threaded-Test GroboUtils Bibliothek hergestellt und getestet, beid Zuweisungen (durch Verkettungen) und einfache Berechnungen (a + j * = j) zu Testprozessor. Und ich habe die folgenden Ergebnisse erhielt:

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 zeigt seine Macht hier übertraf Intel auf 100 Threads.

Hier geht die Multi-Threaded Berechnung Prüfung:

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);
        }

    }

}

Hier geht die Multi-Thread-Zuordnungsprüfung:

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());
        }

    }

}

Andere Tipps

Es ist mein Verständnis, dass Ultrasparc T2-basierte Maschinen bei Performance-pro-Watt-Ziel eher als reine Leistung. Sie könnten versuchen, die Zuweisung der Zeit durch den Stromverbrauch zu teilen und sehen, welche Art von Zahlen bekommen. :)

Gibt es einen Grund Sie laufen 1.4.2 statt 1.6?

Die SunOS Hardware ist langsamer, und die vm kann etwas langsamer als gut.

Ich glaube nicht, dass diese Speicherzuweisung misst. Für den Anfang gibt es eine ganze Menge Charakter Kopieren in a += "allocation driven"; geht. Aber ich vermute, dass der wirkliche Engpass in immer die Ausgabe von System.out.println(...) durch die Netzwerkschichten aus der App auf dem Sun-Server zu Ihrer Remote-Workstation.

Als Experiment versuchen, die innere Schleifenzählung um 10 multipliziert und 100, und sehen, ob der „beschleunigt“, um den Sun-Server in Bezug auf Ihre Workstation.

Eine andere Sache, die Sie könnten versuchen, ist die innere Schleife in einem separaten Verfahren zu bewegen. Es ist möglich, dass da Sie die ganze Arbeit in einem Aufruf von main tun, die JIT-Compiler nie eine Chance, es zu kompilieren bekommen.

(Artificial „Mikro-Benchmarks“ wie diese sind immer anfällig für Effekte wie diese. Ich neige dazu, ihnen zu misstrauen.)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top