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 のエンジニアの 1 人が回答したように、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());
        }

    }

}
于 2009-09-03T07:46:04.753 に答える
0

これがメモリ割り当てを測定しているとは思いません。まず、 では非常に多くの文字のコピーが行われていa += "allocation driven";ます。しかし、本当のボトルネックはSystem.out.println(...)、Sun サーバー上のアプリからリモート ワークステーションにネットワーク層を介して出力を取得することにあるのではないかと思います。

実験として、内側のループ カウントを 10 と 100 で掛けてみて、ワークステーションに比べて Sun サーバーが「高速化」するかどうかを確認してください。

別の方法として、内側のループを別の手順に移動することもできます。すべての作業を の 1 回の呼び出しで行っているためmain、JIT コンパイラがそれをコンパイルする機会を得られない可能性があります。

(このような人工的な「マイクロベンチマーク」は、常にこのような影響を受けやすいです。私はそれらを信用しない傾向があります。)

于 2009-08-28T13:51:47.403 に答える
0

SunOS ハードウェアは遅く、vm も多少遅くなる可能性があります。

于 2009-08-28T12:04:24.107 に答える