简体   繁体   English

为什么D中的for循环比C#中的for循环慢得多?

[英]Why are for loops in D so much slower than for loops in C#?

I have the two following pieces of code in C# and D, the goal was to compare speed in a simple loop. 我在C#和D中有以下两个代码段,目的是在一个简单的循环中比较速度。

D: D:

import std.stdio;
import std.datetime;

void main() {
    StopWatch timer;
    long summer = 0;
    timer.start();
    for (long i = 0; i < 10000000000; i++){
        summer++;
    }
    timer.stop();
    long interval_t = timer.peek().msecs;
    writeln(interval_t);
}

Output: about 30 seconds 输出:约30秒

C#: C#:

using System;
using System.Diagnostics;

class Program{
    static void Main(){
        Stopwatch timer = new Stopwatch();
        timer.Start();
        long summer = 0;
        for(long i = 0; i < 10000000000; i++){
            summer++;
        }
        timer.Stop();
        Console.WriteLine(timer.ElapsedMilliseconds);
    }
}

Output: about 8 seconds 输出:约8秒

Why is the C# code so much faster? 为什么C#代码这么快?

There's a little more to this than just saying: "You didn't turn on the optimizer." 不仅仅是说:“您没有打开优化器。”

At least at a guess, you didn't (initially) turn on the optimizer in either case. 至少在猜测中,您没有(最初)在两种情况下都打开优化器。 Despite this, the C# version without optimization turned on ran almost as fast as the D version with optimization. 尽管如此, 没有优化的C#版本的运行速度几乎与具有优化功能的D版本一样快。 Why would that be? 为什么会这样呢?

The answer stems from the difference in compilation models. 答案源于编译模型的不同。 D does static compilation, so the source is translated to an executable containing machine code, which then executes. D执行静态编译,因此将源代码转换为包含机器代码的可执行文件,然后执行该代码。 The only optimization that happens is whatever is done during that static compilation. 唯一发生的优化是在静态编译期间执行的所有操作。

C#, by contrast, translates from source code to MSIL, an intermediate language (ie, basically a bytecode). 相比之下,C#从源代码转换为MSIL(一种中间语言(即,基本上是字节码))。 That is then translated to machine language by the JIT compiler built into the CLR (common language runtime--Microsoft's virtual machine for MSIL). 然后由内置在CLR中的JIT编译器将其转换为机器语言(公共语言运行时,即Microsoft的MSIL虚拟机)。 You can specify optimization when you run the C# compiler. 您可以在运行C#编译器时指定优化。 That only controls optimization when doing the initial compilation from source to byte code. 这仅在进行从源代码到字节码的初始编译时控制优化。 When you run the code, the JIT compiler does its thing--and it does its optimization whether you specify optimization in the initial translation from source to byte code or not. 运行代码时,无论是否在从源代码到字节码的初始转换中指定优化,JIT编译器都会执行其工作-并且进行优化。 That's why you get much faster results with C# than with D when you didn't specify optimization with either one. 这就是为什么当您未指定任何一个优化时,使用C#会比使用D获得更快的结果的原因。

I feel obliged to add, however, that both results you got (7 and 8 seconds for D and C# respectively) are really pretty lousy. 但是,我不得不补充一下,您得到的两个结果(分别为D和C#分别为7和8秒)都非常糟糕。 A decent optimizer should recognize that the final output didn't depend on the loop at all, and based on that it should eliminate the loop completely. 体面的优化器认识到最终输出根本不依赖于循环,并基于此应完全消除循环。 Just for comparison, I did (about) the most straightforward C++ translation I could: 为了进行比较,我做了(关于)我能做的最简单的C ++翻译:

#include <iostream>
#include <time.h>

int main() {
    long summer = 0;
    auto start = clock();
    for (long i = 0; i < 10000000000; i++)
        summer++;
    std::cout << double(clock() - start) / CLOCKS_PER_SEC;
}

Compiled with VC++ using cl /O2b2 /GL , this consistently shows a time of 0. 使用cl /O2b2 /GL与VC ++一起编译,该时间始终显示为0。

I believe your question should be titled: 我相信你的问题应该标题为:

Why are for loops compiled by < insert your D compiler here > so much slower than for loops compiled by < insert your C# compiler/runtime here >? 为什么用< 在这里插入D编译器 >进行的for循环比< 在这里插入C#编译器/运行时 >进行的for循环慢得多?

Performance can vary dramatically across implementations, and is not a trait of the language itself. 在不同的实现中,性能可能会有很大的不同,这并不是语言本身的特征。 You are probably using DMD, the reference D compiler, which is not known for using a highly-optimizing backend. 您可能正在使用DMD(参考D编译器),但由于使用高度优化的后端而闻名。 For best performance, try the GDC or LDC compilers. 为了获得最佳性能,请尝试使用GDC或LDC编译器。

You should also post the compilation options you used (optimizations may have been enabled with only one compiler). 您还应该发布使用的编译选项(可能只有一个编译器启用了优化)。

See this question for more information: How fast is D compared to C++? 有关更多信息,请参见此问题: D与C ++相比有多快?

Several answers have suggested that an optimizer would optimize the entire loop away. 有几个答案表明,优化器可以优化整个循环。

Mostly they explicitly don't do that as they expect the programmer coded the loop that way as a timing loop. 通常,他们明确地这样做,因为他们期望程序员将循环编码为定时循环。

This technique is often used in hardware drivers to wait for time periods shorter than the time taken to set a timer and handle the timer interrupt. 此技术通常在硬件驱动程序中使用,以等待比设置计时器和处理计时器中断所需的时间短的时间。

This is the reason for the "bogomips" calculation at linux boot time... To calibrate how many iterations of a tight loop per second this particular CPU/compiler can do. 这就是在Linux启动时进行“ bogomips”计算的原因。要校准此特定CPU /编译器每秒可执行的紧密循环迭代次数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM