为什么我的C#代码比我的C代码更快?

6

我要在Windows操作系统上启动这两个控制台应用程序。以下是我的C#代码:

int lineCount = 0;
StreamWriter writer = new StreamWriter("txt1.txt",true);
for (int i = 0; i < 900; i++)
{
    for (int k = 0; k < 900; k++)
    {
        writer.WriteLine("This is a new line" + lineCount);
        lineCount++;
    }
}

writer.Close();
Console.WriteLine("Done!");
Console.ReadLine();

以下是我的C代码。我假设它是C语言,因为我包含了cstdio并使用了标准的fopenfprintf函数。

FILE *file = fopen("text1.txt","a");

for (size_t i = 0; i < 900; i++)
{
    for (size_t k = 0; k < 900; k++)
    {
        fprintf(file, "This is a line\n");
    }
}

fclose(file);
cout << "Done!";

当我启动C#程序时,我立即看到消息“完成!”。当我启动使用标准C函数的C++程序时,它至少要等待2秒钟才能完成并显示消息“完成!”。我只是在玩耍以测试它们的速度,但现在我认为我不知道很多东西。有人能解释一下吗?
注意:这不是“为什么C#比C++运行得更快?”的可能重复问题,因为我没有提供任何控制台输出,如“cout”或“Console.Writeline()”。我只比较文件流机制,它不包括任何可能会中断程序主任务的干扰。

3
这些应用程序并不执行完全相同的操作。虽然C#版本构建了一个临时字符串对象,将其写入文件中,但是C++代码调用fprintf(实际上没有执行任何格式化)。后者仍然需要解析格式字符串。另一个区别:.NET代码不等待本机文件句柄关闭,而非托管代码则需要。 - IInspectable
1
缓冲区可能出了问题,为什么不使用 fstream? - Philip Stuyck
8
也许是因为fprintf会将每一行实时写入文件,而StreamWriter会先写入内存缓冲区,再优化磁盘写入。 - Heavy
可能是为什么C#比C++运行更快?的重复问题。 - Raymond Chen
@PhilipStuyck 程序中花费的时间与 cout 无关。请检查代码。cout 是程序结束的地方。 - ozgur
显示剩余4条评论
2个回答

12

9
"patatatoes"是什么?我想要一个样品。 - Nooble
2
“Patatatoe”是一个打字错误。你知道并不是我们所有人都以英语为母语。 - Philip Stuyck
但是你可以 将苹果和橙子进行比较 - dan04
你不能比较苹果和土豆吗? - intcreator
我并没有说你不能这样做。但是如果你在比较性能,机制应该是相同的。如果一个使用了缓冲区而另一个没有,则它们不同。 - Philip Stuyck
我想知道是谁给这个回答点了踩,以及为什么要这样做。如果我能改进这个回答,我一定会这么做。 - Philip Stuyck

0

我认为这不是比较语言性能的合适方式。

无论如何,C和C#完全是不同的东西,我认为主要的区别在于C#是一种托管语言(有CLR在后台运行,做很多工作像优化等),而C不是。

然而,正如我所说,这两者之间差异太大,无法在这里进行比较。


CLR除了在第一次执行时进行JIT编译代码之外,几乎不做任何事情。它肯定不会在后台执行任何操作,优化也绝对不是它所做的事情之一。它提供的是一个压缩堆,使内存分配变得非常快速,通常比任何给定的CRT快一个(甚至两个)数量级。 - IInspectable
@IInspectable 请查看这些链接,我认为CLR的职责还有更多: http://www.onlinebuff.com/article_roles-of-common-language-runtime-in-dotnet-framework_6.html http://www.c-sharpcorner.com/Blogs/7955/responsibilities-of-clr-in-net-framework.aspx - Felix Av
嗯,是的?除了自动垃圾回收之外,这些都不在后台运行,垃圾回收通常也是手动触发的(IDisposable模式)。你从哪里得到的想法,CLR会执行任何优化呢?此外,如果你想要表达一个观点,请不要发布链接到那些唯一参考是本特定文章作者的文章。 - IInspectable
链接文章中的第三句话是:“Common Language Runtime (CLR) 的主要功能是将托管代码转换为本机代码,然后执行程序。”这太糟糕了。不,CLR绝对不是这样做的。CLR消耗IL。一个值得信赖的发布者会知道区别。但这个孩子不知道。 - IInspectable

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接