简单 Java 程序在 Windows 2008 服务器上运行缓慢

Simple Java programm runs slow on Windows 2008 Server

为什么我的简单 Java 程序在我的本地计算机上运行很快并且 在 Windows 2008 服务器上太慢了?

程序代码:

public static void main(String[] args) {
    long startTime;
    long endTime;
    long totalTime;

    startTime = System.currentTimeMillis();

    for (int a=1; a < 100000; a++) {
        System.out.println("Checking");

    }

    endTime   = System.currentTimeMillis();
    totalTime = endTime - startTime;
    System.out.println("TEST1 time:"+totalTime);

    startTime = System.currentTimeMillis();

    double sum = 0; 
    for (int a=1; a < 1000000; a++) {
        int input = 100;

        for(int counter=1;counter<input;counter++){
            sum += Math.pow(-1,counter + 1)/((2*counter) - 1);
        }

    }

    endTime   = System.currentTimeMillis();
    totalTime = endTime - startTime;
    System.out.println("TEST2 time:"+totalTime+" pi="+sum);
}

本地计算机输出:

Checking
Checking
Checking
Checking
TEST1 time:427
TEST2 time:7261 pi=787922.5634628027

Windows 服务器输出:

Checking
Checking
Checking
Checking
Checking
Checking
TEST1 time:15688
TEST2 time:25280 pi=787922.5634628027

本地计算机硬件和软件: 英特尔酷睿 (TM) i7-2600 CPU @ 3.40GHz Windows 7 专业 8G内存

服务器软硬件:

英特尔至强(R) CPU E5-2603 @ 1.60GHz 8G内存 Windows Server 2008 标准版本 6.0

计算机和服务器都没有其他进程。

可能我必须对 java 虚拟机应用一些参数?

我会看一下处理器的差异。服务器系统大部分时间都针对将内容写入磁盘进行了优化,而不是进行计算。仅看处理器速度,根据该信息,它们是完全不同的 3.4 GHz 和 1.6 GHz 我会说 3.4 应该比 1.6 GHz 快得多。

为了确保找到一些关于这两个系统的 benchmark 信息。

当然,因为服务器处理器要慢得多,对我来说这似乎是完美的结果,根据我的计算(对于这个测试)XEON 1.6 Ghz 处理器的计算效率(每 Ghz)是 i7 处理器的 61% .但是,i7 还可以按需将频率从 3.4 提高到 3.8 Ghz (Turbo Bost),因此这可能会影响您的测试。尝试安装另一个 java VM 并重复该测试。如果您在那之后不确定,请尝试 运行 在 linux 上进行此操作(运行 实时 linux 图像或带有 java 的内容)。影响结果的因素有很多,内存速度是另一个因素。您还可以比较处理器的 GFLOPS 值,这可以给您一些关于效率的提示,但正如您问题下方的一些评论中所述,微基准测试在衡量某些方面并不是很有用。

当您测试通常不会编写的次优代码时,您正在测试该处理器的某些特定行为。很有可能一种处理器设计执行一种操作的速度比另一种慢得多,但总的来说,在实际程序中这不会出现。

最简单的解决方案是尝试优化代码,您可能会发现它在两台机器上都快得多。

double sum = 0; 
for (int a=1; a < 1000000; a++) {
    int input = 100;

    for(int counter = 1; counter < input; counter += 2){
        sum += 1.0 / (2 * counter - 1) - 1 / (2 * counter + 1);
        // or
        // sum += 2.0 / ((2 * counter - 1) * (2 * counter + 1));
    }
}

注意:Math.pow 是一个非常昂贵的操作。