Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Java的执行速度似乎比C++;-第二部分 介绍_Java_C++_Visual Studio 2010_Netbeans7.0 - Fatal编程技术网

为什么Java的执行速度似乎比C++;-第二部分 介绍

为什么Java的执行速度似乎比C++;-第二部分 介绍,java,c++,visual-studio-2010,netbeans7.0,Java,C++,Visual Studio 2010,Netbeans7.0,这是我之前问的问题的后续问题:。通过这篇文章,我学到了一些重要的东西: Li >我没有使用Ctrl +F5编译和运行VisualStudioC++快照上的C++代码,这导致调试速度减慢代码执行。 向量在处理数据数组方面与指针一样好(如果不是更好的话) 我的C++很糟糕。^ ^ 更好的执行时间测试是迭代,而不是递归 我试图编写一个更简单的程序,它不使用指针(或Java等价物中的数组),并且执行起来非常简单。即使这样,java执行速度也比C++执行快。我做错了什么 代码: 爪哇: 更新2: 我用

这是我之前问的问题的后续问题:。通过这篇文章,我学到了一些重要的东西:

<> Li >我没有使用Ctrl +F5编译和运行VisualStudioC++快照上的C++代码,这导致调试速度减慢代码执行。
  • 向量在处理数据数组方面与指针一样好(如果不是更好的话)
  • 我的C++很糟糕。^ ^ <李>
  • 更好的执行时间测试是迭代,而不是递归
  • 我试图编写一个更简单的程序,它不使用指针(或Java等价物中的数组),并且执行起来非常简单。即使这样,java执行速度也比C++执行快。我做错了什么

    代码: 爪哇: 更新2:

    我用新的回合函数改变C++代码,我更新了执行时间。 更新3: 多亏了史蒂夫·汤森和洛杜维克,我找到了问题的答案。在编译我的代码到程序集并对其进行评估之后,我发现C++程序集比java程序集创建更多的内存动作。这是因为我的JDK使用的是X64编译器,而我的VisualStudioExpress C++不能使用X64架构,因此本质上是较慢的。因此,我安装了WindowsSDK7.1,并使用这些编译器编译我的代码(在发行版中,使用ctrl+F5)。目前,时间比率为:

    C++:~2.2秒 Java:~4.6秒


    <>现在我可以编译C++中的所有代码,最终得到我的算法所需的速度。p> 这是因为打印了值。与实际循环无关。

    您肯定不想对输出计时。删除每个循环中的输出语句并重新运行,以便更好地比较您真正感兴趣的内容。否则,您还需要对输出功能和视频驱动程序进行基准测试。产生的速度实际上可能取决于您运行的控制台窗口在测试时是否被遮挡或最小化

    确保C++中没有运行调试生成。这将比发布慢得多,与启动流程的方式无关

    编辑:我在本地复制了这个测试场景,无法得到相同的结果。修改代码(如下)以删除输出后,Java需要5.40754388秒

    public static void main(String args[]) { // Number of iterations 
        double iterations = 1E8;
        double temp; // Create the variables for timing
        double start;
        int matches = 0;
        double end;
        double duration;
        // end - start //Run performance test
        System.out.println("Start");
        start = System.nanoTime();
        for (double i = 0; i < iterations; i += 1) {
            // Overhead and display
            temp = Math.log10(i);
            if (Math.round(temp) == temp) {
                ++matches;
            }
        }
        end = System.nanoTime();
        System.out.println("End");
        // Output performance test results
        duration = (end - start) / 1E9;
        System.out.println("Duration: " + duration);
    }
    
    publicstaticvoidmain(字符串args[]){//迭代次数
    双迭代=1E8;
    double temp;//创建用于计时的变量
    双启动;
    int匹配=0;
    双端;
    双倍持续时间;
    //结束-开始//运行性能测试
    系统输出打印项次(“开始”);
    start=System.nanoTime();
    对于(双i=0;i
    下面的C++代码需要5062毫秒。这是Windows上的JDK 6u21和VC++10 Express的代码

    unsigned int count(1E8);
    DWORD end;
    DWORD start(::GetTickCount());
    double next = 0.0;
    
    int matches(0);
    for (int i = 0; i < count; ++i)
    {
        double temp = log10(double(i));
        if (temp == floor(temp + 0.5))
        {
            ++count;
        }
    }
    
    end = ::GetTickCount();
    std::cout << end - start << "ms for " << 100000000 << " log10s" << std::endl;
    
    无符号整数计数(1E8);
    德沃德端;
    DWORD start(::GetTickCount());
    下一步加倍=0.0;
    int匹配(0);
    对于(int i=0;iSTD::CUT> P>这是一个安全的假设,任何时候你看到java都优于C++,尤其是在这么大的范围内,你做了一些错事。因为这是第二个关于这种微观优化的问题,我觉得我应该建议找一个不那么无用的爱好

    <>这回答了你的问题:你使用C++(实际上,你的操作系统)是错误的。至于隐含的问题(如何?),很简单:
    endl
    刷新流,Java继续对其进行缓冲。将
    cout
    行替换为:

    cout << temp << "\n";
    

    <代码> cOUT 如@ Mat注释,您的C++ <代码>圆< /C> >与javas<代码>数学不一样。表示
    Math.round
    (长)Math.floor(a+0.5d)
    是相同的


    注意,在C++中,不向长转换将更快(也可能在java中)。

    可能想查看< /P> <> P>可能有一大堆因素可以解释为什么java代码运行得比C++代码快。其中一个因素可能是,对于这个测试用例,Java代码更快。我甚至不认为这是一种语言比另一种语言快的声明。


    如果我要对您的工作方式做一个更改,我会使用
    time
    命令将代码移植到linux和time runtime。恭喜,你刚刚删除了整个Windows .h文件。

    < p>只是总结了其他人在这里所说的:C++ iSoFrand功能与java中的不同。在C++输出中,IOFFROW在输出每个字符之前创建一个称为哨兵的内部类型。例如,ostream::sentry使用RAII习惯用法来确保流处于一致状态。在多线程环境(在许多情况下是默认环境)中,在打印每个字符以避免竞争条件后,sentry还用于锁定互斥对象并将其解锁。互斥锁/解锁操作非常昂贵,这就是您面临这种减速的原因

    Java转向另一个方向,对整个输出字符串只锁定/解锁互斥锁一次。这就是为什么如果您要从多个线程输出到cout,您会看到非常混乱的输出,但所有字符都会在那里

    <> P>如果您直接使用流缓冲区,只刷新输出,就可以使C++流性能。为了测试这种行为,只需关闭测试的线程支持,C++的可执行文件就应该运行得更快。 我解放军
    public static void main(String args[]) { // Number of iterations 
        double iterations = 1E8;
        double temp; // Create the variables for timing
        double start;
        int matches = 0;
        double end;
        double duration;
        // end - start //Run performance test
        System.out.println("Start");
        start = System.nanoTime();
        for (double i = 0; i < iterations; i += 1) {
            // Overhead and display
            temp = Math.log10(i);
            if (Math.round(temp) == temp) {
                ++matches;
            }
        }
        end = System.nanoTime();
        System.out.println("End");
        // Output performance test results
        duration = (end - start) / 1E9;
        System.out.println("Duration: " + duration);
    }
    
    unsigned int count(1E8);
    DWORD end;
    DWORD start(::GetTickCount());
    double next = 0.0;
    
    int matches(0);
    for (int i = 0; i < count; ++i)
    {
        double temp = log10(double(i));
        if (temp == floor(temp + 0.5))
        {
            ++count;
        }
    }
    
    end = ::GetTickCount();
    std::cout << end - start << "ms for " << 100000000 << " log10s" << std::endl;
    
    cout << temp << "\n";
    
    cout << "test" << '\n';
    
    _Myt& __CLR_OR_THIS_CALL operator<<(double _Val)
        {// insert a double
        ios_base::iostate _State = ios_base::goodbit;
        const sentry _Ok(*this);
        ...
        }
    
    template<class _Elem,   class _Traits>
    class basic_ostream
      {
      class _Sentry_base
      {
        ///...
    
      __CLR_OR_THIS_CALL _Sentry_base(_Myt& _Ostr)
            : _Myostr(_Ostr)
            {   // lock the stream buffer, if there
            if (_Myostr.rdbuf() != 0)
              _Myostr.rdbuf()->_Lock();
            }
    
        ///...
      };
    };
    
    template<class _Elem, class _Traits>
    void basic_streambuf::_Lock()
        {   // set the thread lock
        _Mylock._Lock();
        }
    
    void __thiscall _Mutex::_Lock()
        {   // lock mutex
        _Mtxlock((_Rmtx*)_Mtx);
        }
    
    void  __CLRCALL_PURE_OR_CDECL _Mtxlock(_Rmtx *_Mtx)
        {   /* lock mutex */
      // some additional stuff which is not called...
        EnterCriticalSection(_Mtx);
        }
    
    Multithreaded DLL/Release build:
    
    Start
    -1.#INF
    0
    1
    2
    3
    4
    5
    6
    7
    End
    Duration: 4.43151
    Press any key to continue . . .
    
    Multithreaded DLL/Release with '\n' instead of endl
    
    Start
    -1.#INF
    0
    1
    2
    3
    4
    5
    6
    7
    End
    Duration: 4.13076
    Press any key to continue . . .
    
    inline bool output_double(double const& val)
    {
      typedef num_put<char> facet;
      facet const& nput_facet = use_facet<facet>(cout.getloc());
    
      if(!nput_facet.put(facet::iter_type(cout.rdbuf()), cout, cout.fill(), val).failed())
        return cout.rdbuf()->sputc('\n')!='\n';
      return false;
    }
    
    Multithreaded DLL/Release without locks by directly writing to streambuf
    
    Start
    -1.#INF
    0
    1
    2
    3
    4
    5
    6
    7
    End
    Duration: 4.00943
    Press any key to continue . . .
    
    size_t iterations = 100000000; //=1E8
    ...
    //Run performance test
    size_t i;
    cout << "Start" << endl;
    QueryPerformanceCounter(&start);
    for(i=0; i<iterations; ++i)
    {
        //Overhead and display
        temp = log10(double(i));
        if(round(temp) == temp)
          output_double(temp);
    }
    QueryPerformanceCounter(&end);
    cout << "End" << endl;
    ...
    
    Start
    -1.#INF
    0
    1
    2
    3
    4
    5
    6
    7
    End
    Duration: 3.69653
    Press any key to continue . . .
    
    sehe@natty:/tmp$ time java PerformanceTest2 
    
    real    0m5.246s
    user    0m5.250s
    sys 0m0.000s
    
    sehe@natty:/tmp$ time ./t
    
    real    0m5.656s
    user    0m5.650s
    sys 0m0.000s
    
    all: PerformanceTest2 t
    
    PerformanceTest2: PerformanceTest2.java
        javac $<
    
    t: t.cpp
        g++ -g -O2 -ffast-math -march=native $< -o $@
    
    #include <stdio.h>
    #include <cmath>
    
    inline double round(double value)
    {
        return floor(0.5 + value);
    }
    int main()
    {
        //Number of iterations
        double iterations = 1E8;
        double temp;
    
        //Run performance test
        for(double i = 0; i < iterations; i += 1)
        {
            //Overhead and display
            temp = log10(i);
            if(round(temp) == temp)
            {
                printf("%F\n", temp);
            }
        }
        return 0;
    }
    
    public class PerformanceTest2
    {
        public static void main(String args[])
        {
            //Number of iterations
            double iterations = 1E8;
            double temp;
    
            //Run performance test
            for(double i = 0; i < iterations; i += 1)
            {
                //Overhead and display
                temp = Math.log10(i);
                if(Math.round(temp) == temp)
                {
                    System.out.println(temp);
                }
            }
        }
    }