Java 内存分配性能(SunOS 与 Windows)

发布于 2024-08-03 16:37:25 字数 1464 浏览 6 评论 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
...

On 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)

I have a very simple unit test that just allocates a lot of Strings:

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

    }

}

On my Windows PC (Intel Core Duo, 2.2GHz, 2GB) this prints on average:

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

On 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 is 1.4.2_18 on both machines. JVM parameters are the same and are:

–server –Xmx256m –Xms256m

Can anyone explain why SUN super server is slower?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

相思故 2024-08-10 16:37:25

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 个线程上的表现优于 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());
        }

    }

}

The CPU is indeed slower on SPARC (1.2Ghz) and as answered by one of the Sun's engineers T2 is usualy 3 times slower for single-threaded application than modern Intel processors. Though, he also stated that in a multi-threaded environment SPARC should be faster.

I have made a multi-threaded test using GroboUtils library and tested both allocations (through concatenations) and simple calculations ( a += j*j ) to test processor. And I've got the following results:

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 shows its power here by outperforming Intel on 100 threads.

Here goes the multi-threaded calculation test:

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

    }

}

Here goes the multi-threaded allocation test:

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

    }

}
梦幻的心爱 2024-08-10 16:37:25

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

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

It's my understanding that UltraSPARC T2-based machines are aimed at performance-per-watt rather than raw performance. You might try dividing the allocation time by the power consumption and see what kind of numbers you get. :)

Is there a reason you're running 1.4.2 instead of 1.6?

半﹌身腐败 2024-08-10 16:37:25

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

The SunOS hardware is slower, and the vm may be somewhat slower as well.

伴我老 2024-08-10 16:37:25

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

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

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

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

I don't think that this is measuring memory allocation. For a start, there is an awful lot of character copying going on in a += "allocation driven";. But I suspect that the real bottleneck is in getting the output from System.out.println(...) through the network layers from the app on the Sun server to your remote workstation.

As an experiment, try multiplying the inner loop count by 10 and 100, and see if that "speeds up" the Sun server relative to your workstation.

Another thing you could try is to move the inner loop into a separate procedure. It is possible that since you are doing all the work in one invocation of main, the JIT compiler never gets a chance to compile it.

(Artificial "micro-benchmarks" like this are always susceptible to effects like these. I tend to distrust them.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文