我有一个很简单的单元测试,只是分配很多字符串:

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(英特尔酷睿双核,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-企业-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

有帮助吗?

解决方案

在CPU确实较慢在SPARC(1.2GHz的),并通过太阳的工程师T2中的一个作为回答为比现代英特尔处理器单线程应用程序慢usualy 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个线程优于英特尔其功率。

下面进入该多线程计算测试:

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

    }

}

其他提示

这是我的理解是基于T2芯片的UltraSPARC机器的目的是出色的每瓦,而不是原始性能。你可能会尝试通过功耗除以分配时间,看看你会得到什么样的数字。 :)

有没有你正在运行1.4.2,而不是1.6的原因是什么?

在的SunOS硬件较慢,并且VM可以是有点慢,以及

我不认为这是测量内存分配。一开始,有一个可怕的很多角色复制的a += "allocation driven";回事。但我怀疑,真正的瓶颈是获得来自System.out.println(...)通过网络层的输出从Sun服务器上的应用到远程工作站。

作为试验,试图通过在10和100乘以内循环计数,并看看是否Sun服务器相对于工作站“加速”。

您可以尝试的另一件事是内循环移动到一个单独的程序。这可能是因为你正在做的各项工作main的一个调用,JIT编译器从来没有得到一个机会来编译它。

(人造“微基准测试”像这样总是容易受到这样的影响。我倾向于不信任他们。)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top