Lust auf einen kleinen Rechner-Test (Java)?



  • [Edit 2: V 0.022: Ergebnisse für aktuelle Java-Version und testDouble hinzugefügt]
    [Edit 1: V 0.02: testSum64Threaded() für Multi-Core Tests und testPrim() hinzugefügt]

    Hier ein kleiner just4fun Benchmark (erhebt keinen Anspruch auf einen vollständigen, realistischen Benchmark!).
    Wer Lust hat kann ja mal seine Ergebnisse zum Vergleichen posten. Erweiterungs/Verbesserungsvorschläge sind willkommen.

    Ergebnisse auf Intel Pentium M @ 1500 MHz und 512 MB DDR1 @ 333 MHz, WinXP, Java 1.6.0_03-b05:

    JBench V 0.022       Test loops: 5
    Sum32 Test...                    best time: 2043 ms
    Sum64 Test...                    best time: 6008 ms
    Sum64 Test using 10 Threads...   best time: 5508 ms
    Sum64 Double Test...             best time: 4076 ms
    RAM Test...                      best time: 3716 ms
    Prim Test (SOE)...               best time: 9754 ms
    

    Ergebnisse auf Intel Pentium M @ 1500 MHz und 512 MB DDR1 @ 333 MHz, WinXP, Java 1.5.0:

    JBench V 0.022      Test loops: 5
    Sum32 Test...                    best time: 3535 ms
    Sum64 Test...                    best time: 7581 ms
    Sum64 Test using 10 Threads...   best time: 7571 ms
    Sum64 Double Test...             best time: 6309 ms
    RAM Test...                      best time: 3926 ms
    Prim Test (SOE)...               best time: 12108 ms
    

    Ergebnisse auf Core2Duo @ 1,86 GHz und DDR2 @ 667 MHz, WinXP, Java 1.6.0_02:

    JBench V 0.02       Test loops: 5
    Sum32 Test...                    best time: 1125 ms
    Sum64 Test...                    best time: 4109 ms
    Sum64 Test using 10 Threads...   best time: 1984 ms
    RAM Test...                      best time: 2015 ms
    Prim Test (SOE)...               best time: 3828 ms
    
    class JBench{
    public final static String APPNAME = "JBench V 0.022";
    public final static int THREADCOUNT = 10;
    public final static int TESTLOOPS = 5;
    public final static long SUM_MAX = 1000000000;
    private static long dontOptimizeResultToDeath = 0;
    
    public static int testSum32(){
    	int sum = 0;	
    	int max = (int) SUM_MAX;
    	long startTime = System.currentTimeMillis();		
    	for(int i = 0; i < max; i++) sum +=  i;	
    	dontOptimizeResultToDeath += sum;		
    	return (int) (System.currentTimeMillis() - startTime);	
    }
    
    public static int testSum64(){
    	long sum = 0;	
    	long startTime = System.currentTimeMillis();		
    	for(long i = 0; i < SUM_MAX; i++) sum +=  i;	
    	dontOptimizeResultToDeath += sum;				
    	return (int) (System.currentTimeMillis() - startTime);	
    }
    
    public static int testSumDouble(){
    	double sum = 0;	
    	double max = (double) SUM_MAX;
    	long startTime = System.currentTimeMillis();		
    	for(double i = 0d; i < max; i+= 1d) sum += i;	
    	dontOptimizeResultToDeath += (long)sum;		
    	return (int) (System.currentTimeMillis() - startTime);	
    }
    
    public static int testMem(){
    	int SIZE = 10000000;
    	int arr[] = new int[SIZE];
    	for(int i = 0; i < SIZE; i++) arr[i] = i;
    
    	long startTime = System.currentTimeMillis();
    	for(int j = 0; j < 50; j++)	
    		for(int i = 0; i < SIZE; i++)
    			arr[i] = arr[SIZE-i-1];				
    	return (int) (System.currentTimeMillis() - startTime);	
    }
    
    public static int testSum64Threaded() throws InterruptedException {
    	long sum = 0;
    
    	if(SUM_MAX%THREADCOUNT != 0)
    		System.out.println("\nWarning: SUM_MAX should be dividable by THREADCOUNT for correct sum result!");
    
    	long startTime = System.currentTimeMillis(); 
    
    	Sum64Thread t[] = new Sum64Thread[THREADCOUNT];
    	for(int part = 0; part < THREADCOUNT; part++){	
    		t[part] = new Sum64Thread(SUM_MAX, THREADCOUNT, part);
    		t[part].setPriority(Thread.NORM_PRIORITY);
    		t[part].start();
    	}  	
    
    	boolean ready = false;
    	while( !ready ) {
    		Thread.sleep(10);
    		for(int part = 0; part < THREADCOUNT; part++){
    				if( !t[part].ready() )	break;
    				if( part == THREADCOUNT-1 ) ready = true;		
    		}	    
    	}
    
    	for(int part = 0; part < THREADCOUNT; part++) sum += t[part].getResult(); 
    	//System.out.println(sum); // sum = 499999999500000000
    	dontOptimizeResultToDeath += sum;							
    	return (int) (System.currentTimeMillis() - startTime);			
    }
    
    public static int testPrim(){		
    	long startTime = System.currentTimeMillis();
    	dontOptimizeResultToDeath += isPrim( 22212576559639469L )? 1 : 0;			
    	return (int) (System.currentTimeMillis() - startTime);	
    }
    
    private static boolean isPrim(long num) {
    	if(num < 2) return false;
    	if(num == 2) return true;
    	long sqrt = (long) Math.sqrt(num) +1;
    	for(long i = 2; i < sqrt; i++) if( num%i == 0 ) return false;
    	return true;
    }
    
    public static void test() throws Exception {	
    
    	System.out.print("Sum32 Test...                    ");
    	int minTime = Integer.MAX_VALUE; 
    	for(int i = 0; i < TESTLOOPS; i++){
    		int t = testSum32();
    		if( t < minTime ) minTime = t;			
    	}
    	System.out.println("best time: " + minTime + " ms");	
    
    	System.out.print("Sum64 Test...                    ");
    	minTime = Integer.MAX_VALUE; 
    	for(int i = 0; i < TESTLOOPS; i++){
    		int t = testSum64();
    		if( t < minTime ) minTime = t;			
    	}
    	System.out.println("best time: " + minTime + " ms");	
    
    	System.out.print("Sum64 Test using " + THREADCOUNT + " Threads...   ");
    	minTime = Integer.MAX_VALUE; 
    	for(int i = 0; i < TESTLOOPS; i++){
    		int t = testSum64Threaded();
    		if( t < minTime ) minTime = t;			
    	}
    	System.out.println("best time: " + minTime + " ms");	
    
    	System.out.print("Sum64 Double Test...             ");
    	minTime = Integer.MAX_VALUE; 
    	for(int i = 0; i < TESTLOOPS; i++){
    		int t = testSumDouble();
    		if( t < minTime ) minTime = t;			
    	}
    	System.out.println("best time: " + minTime + " ms");	
    
    	System.out.print("RAM Test...                      ");
    	minTime = Integer.MAX_VALUE;
    	for(int i = 0; i < TESTLOOPS; i++){
    		int t = testMem();
    		if( t < minTime ) minTime = t;		
    	}
    	System.out.println("best time: " + minTime + " ms");
    
    	System.out.print("Prim Test (SOE)...               ");
    	minTime = Integer.MAX_VALUE;
    	for(int i = 0; i < TESTLOOPS; i++){
    		int t = testPrim();
    		if( t < minTime ) minTime = t;		
    	}
    	System.out.println("best time: " + minTime + " ms");	
    
    }
    
    public static void main(String [] args) {
    	System.out.println(APPNAME + "       Test loops: " + TESTLOOPS);	
    	try{ test(); } catch(Exception e){ System.err.println(e); }
    } 
    }
    
    class Sum64Thread extends Thread{
    	private int part, threadcount;
    	private long max, result;
    	private boolean ready = false;
    
    	public Sum64Thread(long max, int threadcount, int part){ this.threadcount = threadcount; this.max = max; this.part = part; }
    	public boolean ready(){ return ready; }
    	public long getResult(){ return result; }
    
    	public void run() {
    		long sum = 0;
    		long start = part*(max/threadcount);
    		long end = (part+1)*(max/threadcount);
    		for(long i = start; i < end; i++) sum +=  i;	
    		result = sum; 
    		ready = true;   
        }   
    }
    


  • Mach mal nen selbstausführendes Jar file draus^^



  • Ich kann Dir ein paar Zeilen für eine Batch-Datei anbieten 😉

    javac -O *.java
    java JBench >> results.txt
    pause
    

    Wers Ergebnis dirket sehen will lässt ">> results.txt" weg.



  • Test V 0.01
    Sum32 Test...best time is 890 ms
    Sum64 Test...best time is 3078 ms
    Mem Test...best time is 1437 ms
    

    Intel C2D E6600 @ 2,4 GHz, 2GB DDR2 @ 800
    Unter XP 32bit und Java 1.6.0_03-b05

    PS: CPU war aber nur zu 51% ausgelastet. Wieso das?



  • LeGaN schrieb:

    PS: CPU war aber nur zu 51% ausgelastet. Wieso das?

    Du weißt schon, dass du eine CPU mit 2 Kernen hast?
    Das Programm hat nur einen Thread und der kann nur auf einem Kern laufen => ~50% Gesamtauslastung.



  • LeGaN schrieb:

    PS: CPU war aber nur zu 51% ausgelastet. Wieso das?

    Weil du ein Dual Core hast ...



  • robot schrieb:

    Ich kann Dir ein paar Zeilen für eine Batch-Datei anbieten 😉

    javac Test.java
    java Test >> results.txt
    pause

    Wers Ergebnis dirket sehen will lässt ">> results.txt" weg.

    Achja, habe es hier mit JRE 1.5.0 getestet.

    Ich habe kein Java SDK.



  • this->that schrieb:

    Ich habe kein Java SDK.

    Aber wenn hier wildfremde Leute Executables hochladen, führst Du sie aus?

    Test V 0.01
    Sum32 Test...best time is 5593 ms
    Sum64 Test...best time is 36139 ms
    Mem Test...best time is 14799 ms
    

    866MHz G4, 640MB RAM.



  • nman schrieb:

    Aber wenn hier wildfremde Leute Executables hochladen, führst Du sie aus?

    Da ich den Thread kenne und die Gefahr einigermaßen einschätzen kann: Ja.



  • Wie willst Du die Gefahr einschätzen können, wenn Du die Executable bekommst? Was hindert uns daran, da irgendwo einen recursiveDeleteRootDir()-Aufruf reinzupacken? (Oder führst Du sowas in einer Sandbox aus?)



  • schirrmie schrieb:

    LeGaN schrieb:

    PS: CPU war aber nur zu 51% ausgelastet. Wieso das?

    Weil du ein Dual Core hast ...

    Das ist mir klar. Ich meinte auch, 51% auf _einem_ Kern.



  • nman schrieb:

    Wie willst Du die Gefahr einschätzen können, wenn Du die Executable bekommst? Was hindert uns daran, da irgendwo einen recursiveDeleteRootDir()-Aufruf reinzupacken? (Oder führst Du sowas in einer Sandbox aus?)

    Ganz einfach: Ich gehe davon aus, dass robot kein gemeiner Sack ist und jetzt extra für mich einen Virus schreibt und den dann anstelle seines Benchmarks hochlädt.



  • LeGaN schrieb:

    schirrmie schrieb:

    LeGaN schrieb:

    PS: CPU war aber nur zu 51% ausgelastet. Wieso das?

    Weil du ein Dual Core hast ...

    Das ist mir klar. Ich meinte auch, 51% auf _einem_ Kern.

    Ich habs grad nochmal laufen lassen. Nun ist wies es soll auf einem Kern 100%, auf dem andrem nüscht. Nach ein paar weiteren Male kam wieder das vor, dass auf einem Kern nicht die vollen 100% waren. Der Teil, der auf dem einen bis zu den 100% gefehlt haben, waren auf dem anderen Kern zu sehen. Zeigt da der Taskmanager was falsch an, oder trickst da die VM etwas rum?



  • Damit die Multi-Core Besitzer auch auf ihre Kosten kommen, habe ich noch einen Test mit Threads eingebaut (siehe erstes Posting).

    @this->that: Wenn Du mir sagst, wo ich die Files uploaden kann, ohne viel Aufwand zu haben (Zwangsregistrierung, Werbe-Schrott, ...), dann lad ich das auch gerne hoch. Ansonsten schnell das SDK installieren, sonst kommst Du nicht in den (J)Himmel 😉 : http://java.sun.com/javase/downloads/?intcmp=1281



  • ... oder im Weltnetz übersetzen lassen:

    http://www.innovation.ch/java/java_compile.html

    hab "Optimize" und 1.5.0 eingestellt.

    🙂

    Ergebnisse auf einem AthlonX2 4200+

    Test V 0.02 Test loops: 5
    Sum32 Test... best time: 1828 ms
    Sum64 Test... best time: 4484 ms
    Sum64 Test using 10 Threads... best time: 2390 ms
    RAM Test... best time: 2125 ms
    Prim Test (SOE)... best time: 8281 ms

    Durchlauf Nr. 2:

    Test V 0.02 Test loops: 5
    Sum32 Test... best time: 1828 ms
    Sum64 Test... best time: 4813 ms
    Sum64 Test using 10 Threads... best time: 2547 ms
    RAM Test... best time: 2172 ms
    Prim Test (SOE)... best time: 8188 ms

    Wobei da nischt mit Multiprozessor uns so zu merken ist, das Ganze läuft auf einem Kern mit 100%



  • Intel P4 @ 3 Ghz:

    Sum32 Test...                    best time: 1031 ms
    Sum64 Test...                    best time: 4125 ms
    Sum64 Test using 10 Threads...   best time: 4781 ms
    RAM Test...                      best time: 4499 ms
    Prim Test (SOE)...               best time: 9390 ms
    

    So Leute und jetzt portieren wir das Ding auf C++ und gucken welche Sprache besser ist 😃 😃

    Bitte beachten sie die Sicherheitslinie. Betreten der Zone auf eigenes Risiko!

    -----------------------------------
    you are entering the flamewars zone



  • Intel C2D @ 3,33GHz, Vista 64, erstellt mit dem Webcompiledingens mit gleichen Einstellungen wie F98.

    Sum32 Test...                    best time: 639 ms
    Sum64 Test...                    best time: 2315 ms
    Sum64 Test using 10 Threads...   best time: 1123 ms
    RAM Test...                      best time: 1184 ms
    Prim Test (SOE)...               best time: 2162 ms
    


  • F98 schrieb:

    ... oder im Weltnetz übersetzen lassen:

    http://www.innovation.ch/java/java_compile.html

    Ah, Danke für den Tipp. 🙂

    F98 schrieb:

    Wobei da nischt mit Multiprozessor uns so zu merken ist, das Ganze läuft auf einem Kern mit 100%

    Ja, nutzt auch alles nur einen Thread, bis auf den "Sum64 Test using 10 Threads". Dort werden bis zu 10 Kerne genutzt. Das siehst Du auch daran, dass auf Deinem X2 der Sum64 mit 10 Threads fast doppelt so schnell ist wie der Sum64 Test ohne Threads.

    Cpp_Junky schrieb:

    So Leute und jetzt portieren wir das Ding auf C++ und gucken welche Sprache besser ist

    Hab es mal fix umgematscht und mit dem VC++ kompiliert (Datentyp __int64 für sum64). Die Ergebnisse beim Rechnen sind etwa um den Faktor 1,1 - 1,8 schneller. Der RAM Test war fast exakt gleich schnell wie unter Java (ohne speziell optimierten Code, einfach nur so wie in Java gelassen). Ich finde es aber trotzdem interessanter den Test unter Java mit der JVM zu machen, da dies (bei gleicher Version) einheitlichere Ergebnisse liefert. Die C++ Ergebnisse sind sicher stark vom jeweiligen Kompiler + Einstellungen abhängig. Wenn wer unbedingt will, kann ich den Code ja trotzdem mal posten.



  • 16:20:37 mastercpp@chi ~ % javac -O JBench.java            
    16:20:46 mastercpp@chi ~ % java JBench                  
    JBench V 0.02       Test loops: 5
    Sum32 Test...                    best time: 0 ms
    Sum64 Test...                    best time: 1280 ms
    Sum64 Test using 10 Threads...   best time: 1729 ms
    RAM Test...                      best time: 1854 ms
    Prim Test (SOE)...               best time: 5103 ms
    
    16:21:51 mastercpp@chi ~ % gcj -O3 --main=JBench JBench.java 
    16:22:03 mastercpp@chi ~ % ./a.out 
    JBench V 0.02       Test loops: 5
    Sum32 Test...                    best time: 0 ms
    Sum64 Test...                    best time: 0 ms
    Sum64 Test using 10 Threads...   best time: 865 ms
    RAM Test...                      best time: 1941 ms
    Prim Test (SOE)...               best time: 5495 ms
    
    16:24:51 mastercpp@chi ~ % java -version 
    java version "1.6.0_03"
    Java(TM) SE Runtime Environment (build 1.6.0_03-b05)
    Java HotSpot(TM) 64-Bit Server VM (build 1.6.0_03-b05, mixed mode)
    
    16:24:55 mastercpp@chi ~ % gcj --version
    gcj (GCC) 4.1.2 (Gentoo 4.1.2 p1.0.1)
    Copyright (C) 2006 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    

    0 ms?



  • mastercpp schrieb:

    16:20:37 mastercpp@chi ~ % javac -O JBench.java            
    16:20:46 mastercpp@chi ~ % java JBench                  
    JBench V 0.02       Test loops: 5
    Sum32 Test...                    best time: 0 ms
    Sum64 Test...                    best time: 1280 ms
    Sum64 Test using 10 Threads...   best time: 1729 ms
    RAM Test...                      best time: 1854 ms
    Prim Test (SOE)...               best time: 5103 ms
    

    0 ms?

    Das mit dem 0 ms ist mir unter Java auch noch nicht passiert. Ich vermute, dass die aktuelle Version von javac das kaputt optimiert, weil er merkt, dass das Ergebnis (sum) nicht weiter verwertet wird. Dass er so schlau ist und die Summenformel sum = (max+1)*max/2 anwendet kann ich mir noch nicht vorstellen.

    Ich hab das Ergebnis mal einer Membervariablen zugewiesen, so dass er eigentlich zum Ausführen der Schleife gezwungen sein müsste. Kannst Dus evtl. nochmal testen? (siehe erstes Posting)



  • @robot: Hol Dir mal ein aktuelles JDK und vergleiche Deine Java 5 Ergebnisse damit. Die behaupten doch tatsächlich schon wieder, dass das aktuelle Java 6 teilweise schneller als Java 5 sein soll:

    http://java.sun.com/performance/reference/whitepapers/6_performance.html


Anmelden zum Antworten