c# - C++ (Intel) vs Java (Hotspot) vs C# 基准问题(包括代码和结果)

标签 c# java c++ performance caching

我一直在比较三种主要语言之间的原始 CPU 性能速度(代码和结果如下)。我很好奇主要语言如何比较原始计算能力。我有一个理论,即在不涉及内存开销的情况下,Java 和 C# 可以与 C++ 相媲美。

我的问题:

1) 已编辑(C++ 时序现在更真实)

2) 我是否认为 JVM 在第一次迭代中花费了很长时间,但在第二次迭代中它已经完成分析并因此进行了优化? Hotspot 是如何知道在我的外部循环的第一次迭代之后而不是中途完成优化的?

3) 为什么 C# 不像 Java 那样执行并且在一开始就进行了大量优化? C# 与 Java 有何不同?为什么 C# 速度较慢 - 仅仅是因为优化较少吗?

4) C# 测试时间在 2246 和 2262 毫秒之间振荡是否有任何具体原因,这可能是两个不同的时间,因为 CPU 有两个内核?

编辑:更新代码以在 C# 代码中显示秒表用法。

编辑:更正 C++ 计时代码和结果

设置:

  • C++:VS2010 和英特尔编译器(在 Release模式下构建,优化: O2,启用内部功能:是,支持大小或速度:两者都不是, 省略帧指针:不,启用光纤安全优化:不,整个 程序优化:是)

  • Java:Eclipse、Hotspot 64 位编译器版本 17、Java 1.6

  • C#:VS2010 和 .net 4.0(内置 Release模式)

  • CPU:Intel E6600 (2.4GHz),主频 2.7GHz,总线速度 300MHz,内存 8GB,DRAM 频率:375MHz

  • Win 7(64 位)

C++代码:

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <mmsystem.h>
#include <stdio.h>
#include <fstream> 

using namespace std;


double PCFreq = 0.0;
__int64 CounterStart = 0;

void StartCounter()
{
    LARGE_INTEGER li;
    if(!QueryPerformanceFrequency(&li))
        cout << "QueryPerformanceFrequency failed!\n";

    PCFreq = li.QuadPart;

    QueryPerformanceCounter(&li);
    CounterStart = li.QuadPart;
}
double GetCounter()
{
    LARGE_INTEGER li;
    QueryPerformanceCounter(&li);
    return double(li.QuadPart-CounterStart)/PCFreq;
}

static long counter = 0;

int _tmain(int argc, _TCHAR* argv[])
{

    for (int m = 0; m < 10; m++)
    {
        StartCounter();
        counter = 0;

        for (int j = 0; j < 3; j++)
        {
            //Just to test timing is working correctly
            //int* p = new int;

            for (long i = 0; i < 200000000; i++)
            {
                counter++;
            }
        }

        cout << GetCounter()*1000000 << " microseconds" << endl;
    }


    int p = 0;
    cin >> p;
    return 0;
}

C++ 结果:

7.19 microseconds

1.89

2.27

1.51

4.92

10.22

10.22

9.84

9.84

10.6

Java代码:

public class main {

    static long counter = 0;

    public static void main(String[] args) {

        for(int m=0; m<10; m++){
            long start = System.nanoTime();
            counter = 0;

            for(int j=0;j<3; j++){
                for(long i=0; i<200000000; i++){
                    counter++;
                }
            }

            System.out.println(((System.nanoTime()-start)/1000000) + " ms");
        }
    }
}

Java 结果:

5703 milliseconds
471 ms
468 ms
467 ms
469 ms
467 ms
467 ms
467 ms
469 ms
464 ms

C#代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics

namespace t1
{
    class Program
    {
        static long counter = 0;

        static void Main(string[] args)
        {
            for (int m = 0; m < 10; m++)
            {
                Stopwatch s = new Stopwatch();
                s.Start();
                counter = 0;

                for (int j = 0; j < 3; j++)
                {

                    for (long i = 0; i < 200000000; i++)
                    {
                        counter++;
                    }

                }
                s.Stop();
                Console.WriteLine(s.Elapsed.TotalMilliseconds + " ms");
            }

            Console.ReadLine();
        }
    }
}

C# 结果:

2277 milliseconds

2246 ms

2262 ms

2246 ms

2262 ms

2246 ms

2262 ms

2246 ms

2262 ms

2262 ms

最佳答案

您在使用 QueryPerformanceFrequency 的 C++ 代码中遇到逻辑问题:

PCFreq = double(li.QuadPart)/1000000000.0; // <- this is not correct
PCFreq = li.QuadPart;                      // <- this is correct

您应该将 li.QuadPart 分配给 PCFreq 并在您的打印代码中转换为毫秒或纳秒:

// convert from seconds to milliseconds
cout << GetCounter() * 1000.0 << endl;

通过此更改,我可以获得您的 C++ 代码的实际计时。这些时间是否“有效”或对比较有用,我不做评论。

关于c# - C++ (Intel) vs Java (Hotspot) vs C# 基准问题(包括代码和结果),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10260021/

相关文章:

c# - WPF MenuItem 绑定(bind)问题

java - 如何使用struts 1在jsp的对象标记中设置上下文的值

c++ - 尽管类型在析构函数中完全限定,但 std::auto_ptr 崩溃和泄漏

c++ - 矩形的 OpenGL 渐变不起作用

c# - .Net Collection 用于雾化T?

c# - 尝试在 Service Fabric 中容器化和发布 StatelessService 时出现异常

c# - 索引方法 'Class.Method' 错误无法将参数 'log' 绑定(bind)到类型 TraceWriter

java - 如何获取 XMLBeans 中的所有枚举值?

java - 使用 Libvirt Java API 连接到 QEMU

c++ - 如何在阻塞 send() 时模拟 WSAEWOULDBLOCK?