0

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

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 )

4

4 回答 4

2

CPU 在 SPARC (1.2Ghz) 上确实较慢,正如 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 个线程上的表现优于英特尔,从而展示了它的强大功能。

多线程计算测试如下:

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

    }

}
于 2009-09-03T07:46:04.753 回答
1

据我了解,基于 UltraSPARC T2 的机器的目标是每瓦性能,而不是原始性能。您可以尝试将分配时间除以功耗,看看您得到什么样的数字。:)

您运行 1.4.2 而不是 1.6 有什么原因吗?

于 2009-08-28T12:18:39.310 回答
0

SunOS 硬件较慢,虚拟机也可能较慢。

于 2009-08-28T12:04:24.107 回答
0

我不认为这是在测量内存分配。首先,在a += "allocation driven";. 但我怀疑真正的瓶颈在于System.out.println(...)通过网络层从 Sun 服务器上的应用程序获取输出到远程工作站。

作为一个实验,尝试将内部循环计数乘以 10 和 100,看看是否相对于您的工作站“加速”了 Sun 服务器。

您可以尝试的另一件事是将内部循环移动到单独的过程中。由于您在一次调用中完成所有工作main,因此 JIT 编译器可能永远没有机会编译它。

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

于 2009-08-28T13:51:47.403 回答