Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.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
C# 为什么.NET比C++;在这种情况下?_C#_.net_C++_Benchmarking_Fibonacci - Fatal编程技术网

C# 为什么.NET比C++;在这种情况下?

C# 为什么.NET比C++;在这种情况下?,c#,.net,c++,benchmarking,fibonacci,C#,.net,C++,Benchmarking,Fibonacci,确保在IDE之外运行。这是关键 -编辑-我喜欢SLaks评论。“这些答案中的错误信息数量令人震惊。”:D 冷静点,伙计们。你们几乎都错了。我确实做了优化。 结果证明我做的任何优化都不够好。 我使用gettimeofday(我将在下面粘贴代码)在GCC中运行代码,并使用g++-O2 file.cpp,得到的结果略快于C。 也许MS没有在这个特定的情况下创建所需的优化,但是在下载和安装mingw后,我进行了测试,发现速度几乎相同。 似乎是对的。我可以发誓我用我的电脑上的时钟,并用它来计数,发现它慢了

确保在IDE之外运行。这是关键


-编辑-我喜欢SLaks评论。“这些答案中的错误信息数量令人震惊。”:D

冷静点,伙计们。你们几乎都错了。我确实做了优化。 结果证明我做的任何优化都不够好。 我使用gettimeofday(我将在下面粘贴代码)在GCC中运行代码,并使用
g++-O2 file.cpp
,得到的结果略快于C。 也许MS没有在这个特定的情况下创建所需的优化,但是在下载和安装mingw后,我进行了测试,发现速度几乎相同。 似乎是对的。我可以发誓我用我的电脑上的时钟,并用它来计数,发现它慢了,但问题解决了。在MS编译器中,C++速度几乎不慢两倍。

当我的朋友告诉我这件事时,我简直不敢相信。所以我拿了他的密码,在上面放了一些计时器

我用的不是C#。我在C#中不断获得更快的成绩。为什么?无论我使用的是什么数字,.NET版本几乎占了一半的时间

C++版本(错误版本):

#包括
#包括
#包括
#包括
使用名称空间std;
整数fib(整数n)
{
如果(n<2)返回n;
返回fib(n-1)+fib(n-2);
}
int main()
{
__int64时间=0xFFFFFF;
而(1)
{
int n;
//cin>>n;
n=41;
如果(n<0)断裂;
__int64 start=uu rdtsc();
int res=fib(n);
__int64 end=uu rdtsc();

cout如果该代码确实是执行时间的1/2,则可能的原因如下:

    垃圾回收加快了C++代码在C++代码中的执行,如果在上述代码中发生的话,
  • 对控制台的C#写入可能是缓冲的(C++可能没有,或者可能没有那么有效)

可能是在运行测试之前在运行时对方法进行了预JIT…或者控制台是API的包装器,用于在缓冲C++的
cout
代码时输出到控制台..我猜

希望这有帮助, 顺致敬意,
Tom。

不理解垃圾收集或控制台缓冲的答案

< >你的C++中的计时器机制可能有缺陷。

根据调查,您可能会得到错误的基准测试结果

引述:

而这会让时间保持更多 一致性,它会扭曲基准, 在一定的旋转时间内 以前是以较低的时钟频率使用的 操作系统将处理器切换到 更高的比率。这具有 让事情看起来像他们需要的那样 处理器的周期比它们的多 通常会


不是说这是问题所在,但你可能想读一读

也看到这个。。。

<> P>一些主要数值基准的研究认为,由于各种原因,java可能在某些情况下比C++快得多:[8 ] [ 9 ]。 指针使得优化变得困难,因为它们可能指向任意数据,尽管许多C++编译器提供了C99关键字限制,纠正了这个问题。 相比于无限制地使用MalC/C的新的实现实现内存分配的C++实现,java垃圾收集的实现可能具有更好的缓存一致性,因为其分配通常是顺序进行的。 *运行时编译可能会使用运行时可用的其他信息来更有效地优化代码,例如知道代码将在哪个处理器上执行


关于java,但开始处理C运行时和JIT运行时的性能问题。

< P>我认为问题是C++中的时序代码。 从
\uu rdtsc
的MS文档:

生成rdtsc指令,该指令返回处理器时间戳。 处理器时间戳记录自上次重置以来的时钟周期数


也许可以尝试
GetTickCount()
也许C能够在递归调用中展开堆栈?我认为这也可以减少计算量。

我知道.NET编译器有英特尔优化。

1 垃圾收集过程可能会起作用

在C++版本中,程序运行时所有内存管理都会在联机中发生,并将进入最后一个时间。 在.NET中,公共语言运行库(CLR)的垃圾收集器(GC)是不同线程上的一个单独进程,通常在程序完成后清理程序。因此,程序将完成,时间将在内存释放前打印出来。特别是对于通常在完成之前根本不会清理的小程序

这完全取决于垃圾回收实现的细节(如果它以堆的方式对堆栈进行优化),但我认为这在速度增益中起到了部分作用。如果C++版本也被优化,在完成后不释放/清理内存(或者推到程序完成之后)那么我相信你会看到C++的速度增益。 要测试GC:要查看“延迟的.NET GC行为”的作用,请在对象的某些析构函数/终结器方法中设置断点。调试程序将在程序完成后激活并命中这些断点(是的,在Main完成后)

推测2 否则,C#源代码由程序员编译成IL代码(Microsoft字节码指令),在运行时,这些代码又由CLR的即时编译器编译成特定于处理器的指令集(与经典编译程序一样)因此,一旦.NET程序开始运行并第一次运行,它就没有理由变慢。

编辑: 虽然原始C++定时错误(比较周期到毫秒),但更好的时序确实显示了C语言在香草编译器设置上更快。
#include <iostream>
#include <stdio.h>
#include <intrin.h>
#include <windows.h>
using namespace std;

int fib(int n)
{
    if (n < 2) return n;
    return fib(n - 1) + fib(n - 2);
}

int main()
{
    __int64 time = 0xFFFFFFFF;
    while (1)
    {
        int n;
        //cin >> n;
        n = 41;
        if (n < 0) break;
__int64 start = __rdtsc();
        int res = fib(n);
__int64 end = __rdtsc();
        cout << res << endl;
        cout << (float)(end-start)/1000000<<endl;
        break;
    }

    return 0;
}
#include <iostream>
#include <stdio.h>
#include <intrin.h>
#include <windows.h>
using namespace std;

int fib(int n)
{
    if (n < 2) return n;
    return fib(n - 1) + fib(n - 2);
}

int main()
{
    __int64 time = 0xFFFFFFFF;
    while (1)
    {
        int n;
        //cin >> n;
        n = 41;
        if (n < 0) break;
        LARGE_INTEGER start, end, delta, freq;
        ::QueryPerformanceFrequency( &freq );
        ::QueryPerformanceCounter( &start );
        int res = fib(n);
        ::QueryPerformanceCounter( &end );
        delta.QuadPart = end.QuadPart - start.QuadPart;
        cout << res << endl;
        cout << ( delta.QuadPart * 1000 ) / freq.QuadPart <<endl;
break;
    }

    return 0;
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Threading;
using System.IO;

using System.Diagnostics;

namespace fibCSTest
{
    class Program
    {
         static int fib(int n)
         {
            if (n < 2)return n;
            return fib(n - 1) + fib(n - 2);
         }

         static void Main(string[] args)
         {
             //var sw = new Stopwatch();
             //var timer = new PAB.HiPerfTimer();
             var timer = new Stopwatch();
             while (true)
             {
                 int n;
                 //cin >> n;
                 n = 41;
                 if (n < 0) break;
                 timer.Start();
                 int res = fib(n);
                 timer.Stop();
                 Console.WriteLine(res);
                 Console.WriteLine(timer.ElapsedMilliseconds);
                 break;
             }
         }
    }
}
#include <iostream>
#include <stdio.h>
#include <sys/time.h>
using namespace std;

int fib(int n)
{
    if (n < 2) return n;
    return fib(n - 1) + fib(n - 2);
}

int main()
{
    timeval start, end;
    while (1)
    {
        int n;
        //cin >> n;
        n = 41;
        if (n < 0) break;
        gettimeofday(&start, 0);
        int res = fib(n);
        gettimeofday(&end, 0);
        int sec = end.tv_sec - start.tv_sec;
        int usec = end.tv_usec - start.tv_usec;
        cout << res << endl;
        cout << sec << " " << usec <<endl;
        break;
    }

    return 0;
}
int fib(int n)
{
    if (n < 2) return n;
    return fib(n - 1) + fib(n - 2);
}

int main()
{
    __int64 time = 0xFFFFFFFF;
    while (1)
    {
        int n;
        //cin >> n;
        n = 41;
        if (n < 0) break;
        LARGE_INTEGER start, end, delta, freq;
        ::QueryPerformanceFrequency( &freq );
        ::QueryPerformanceCounter( &start );
        int res = fib(n);
        ::QueryPerformanceCounter( &end );
        delta.QuadPart = end.QuadPart - start.QuadPart;
        cout << res << endl;
        cout << ( delta.QuadPart * 1000 ) / freq.QuadPart <<endl;
break;
    }

    return 0;
}
00000000 55               push        ebp  
00000001 8B EC            mov         ebp,esp 
00000003 57               push        edi  
00000004 56               push        esi  
00000005 53               push        ebx  
00000006 8B F1            mov         esi,ecx 
00000008 83 FE 02         cmp         esi,2 
0000000b 7D 07            jge         00000014 
0000000d 8B C6            mov         eax,esi 
0000000f 5B               pop         ebx  
00000010 5E               pop         esi  
00000011 5F               pop         edi  
00000012 5D               pop         ebp  
00000013 C3               ret              
            return fib(n - 1) + fib(n - 2);
00000014 8D 7E FF         lea         edi,[esi-1] 
00000017 83 FF 02         cmp         edi,2 
0000001a 7D 04            jge         00000020 
0000001c 8B DF            mov         ebx,edi 
0000001e EB 19            jmp         00000039 
00000020 8D 4F FF         lea         ecx,[edi-1] 
00000023 FF 15 F8 2F 12 00 call        dword ptr ds:[00122FF8h] 
00000029 8B D8            mov         ebx,eax 
0000002b 4F               dec         edi  
0000002c 4F               dec         edi  
0000002d 8B CF            mov         ecx,edi 
0000002f FF 15 F8 2F 12 00 call        dword ptr ds:[00122FF8h] 
00000035 03 C3            add         eax,ebx 
00000037 8B D8            mov         ebx,eax 
00000039 4E               dec         esi  
0000003a 4E               dec         esi  
0000003b 83 FE 02         cmp         esi,2 
0000003e 7D 04            jge         00000044 
00000040 8B D6            mov         edx,esi 
00000042 EB 19            jmp         0000005D 
00000044 8D 4E FF         lea         ecx,[esi-1] 
00000047 FF 15 F8 2F 12 00 call        dword ptr ds:[00122FF8h] 
0000004d 8B F8            mov         edi,eax 
0000004f 4E               dec         esi  
00000050 4E               dec         esi  
00000051 8B CE            mov         ecx,esi 
00000053 FF 15 F8 2F 12 00 call        dword ptr ds:[00122FF8h] 
00000059 03 C7            add         eax,edi 
0000005b 8B D0            mov         edx,eax 
0000005d 03 DA            add         ebx,edx 
0000005f 8B C3            mov         eax,ebx 
00000061 5B               pop         ebx  
00000062 5E               pop         esi  
00000063 5F               pop         edi  
00000064 5D               pop         ebp  
00000065 C3               ret  
int fib(int n)
{ 
00B31000 56               push        esi  
00B31001 8B F1            mov         esi,ecx 
    if (n < 2) return n; 
00B31003 83 FE 02         cmp         esi,2 
00B31006 7D 04            jge         fib+0Ch (0B3100Ch) 
00B31008 8B C6            mov         eax,esi 
00B3100A 5E               pop         esi  
00B3100B C3               ret              
00B3100C 57               push        edi  
    return fib(n - 1) + fib(n - 2); 
00B3100D 8D 4E FE         lea         ecx,[esi-2] 
00B31010 E8 EB FF FF FF   call        fib (0B31000h) 
00B31015 8D 4E FF         lea         ecx,[esi-1] 
00B31018 8B F8            mov         edi,eax 
00B3101A E8 E1 FF FF FF   call        fib (0B31000h) 
00B3101F 03 C7            add         eax,edi 
00B31021 5F               pop         edi  
00B31022 5E               pop         esi  
} 
00B31023 C3               ret              
int fib(int n);

int fib2(int n) 
{ 
    if (n < 2) return n; 
    return fib(n - 1) + fib(n - 2); 
} 

int fib(int n)
{ 
    if (n < 2) return n; 
    return fib2(n - 1) + fib2(n - 2); 
} 
int fib(int n);

int fib3(int n) 
{ 
    if (n < 2) return n; 
    return fib(n - 1) + fib(n - 2); 
} 

int fib2(int n) 
{ 
    if (n < 2) return n; 
    return fib3(n - 1) + fib3(n - 2); 
} 

int fib(int n)
{ 
    if (n < 2) return n; 
    return fib2(n - 1) + fib2(n - 2); 
} 
IEnumerable<int> Fibonacci()
{
   int n1 = 0;
   int n2 = 1;

   yield return 1;
   while (true)
   {
      int n = n1 + n2;
      n1 = n2;
      n2 = n;
      yield return n;
   }
}
public static int fib(int n)
{
    return Fibonacci().Skip(n).First();
}
template<int N> struct fibonacci
{
    static const int value = fibonacci<N - 1>::value + fibonacci<N - 2>::value;
};

template<> struct fibonacci<1>
{
    static const int value = 1;
};

template<> struct fibonacci<0>
{
    static const int value = 0;
};