[英]Java memory allocation performance (SunOS vs Windows)
我有一個非常簡單的單元測試,只分配了很多字符串:
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());
}
}
}
在我的Windows PC(Intel Core Duo,2.2GHz,2GB)上,平均打印:
...
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
...
在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版本均為1.4.2_18。 JVM參數是相同的,並且是:
–server –Xmx256m –Xms256m
誰能解釋為什么SUN超級服務器比較慢?
( http://www.sun.com/servers/coolthreads/t5120/performance.xml )
在SPARC(1.2Ghz)上,CPU的確確實要慢一些,並且正如Sun的一位工程師所回答的那樣,單線程應用程序的T2通常比現代Intel處理器慢3倍。 不過,他還指出,在多線程環境中,SPARC應該更快。
我使用GroboUtils庫進行了多線程測試,並測試了分配(通過串聯)和簡單的計算(a + = j * j)以測試處理器。 我得到以下結果:
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通過在100個線程上勝過Intel來顯示其強大功能。
這里是多線程計算測試:
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);
}
}
}
這是多線程分配測試:
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());
}
}
}
據我了解,基於UltraSPARC T2的計算機的目標是每瓦性能而不是原始性能。 您可以嘗試將分配時間除以功耗,然后看得出哪種數字。 :)
您運行1.4.2而不是1.6是有原因的嗎?
SunOS硬件較慢,而vm也可能較慢。
我不認為這正在衡量內存分配。 首先,在a += "allocation driven";
中進行a += "allocation driven";
大量的字符復制a += "allocation driven";
。 但是我懷疑真正的瓶頸在於從Sun服務器上的應用程序到遠程工作站的網絡層從System.out.println(...)
獲取輸出。
作為實驗,請嘗試將內部循環計數乘以10和100,然后查看是否相對於您的工作站“加速”了Sun服務器。
您可以嘗試的另一件事是將內部循環移動到單獨的過程中。 由於您可能在一次main
調用中完成所有工作,因此JIT編譯器永遠不會獲得編譯它的機會。
(這樣的人為“微基准”總是容易受到此類影響。我傾向於不信任它們。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.