C++ 和 C# 速度测试 - 奇怪的结果
Posted
技术标签:
【中文标题】C++ 和 C# 速度测试 - 奇怪的结果【英文标题】:C++ and C# Speed Test - Strange Result 【发布时间】:2014-06-19 05:08:49 【问题描述】:对于需要高速计算的新项目,我尝试在 C++ 和 C# 之间进行选择。我一直听说 C# 在速度上是合理的。我知道它比 C 和 C++ 慢,但我的例外是差异并不大!所以我用 C++ 和 C# 编写了两个代码来自己测试它们。
结果是 C++ 大约是 5:09 到 5:55 秒,而 C# 是 11408 到 11960 秒。
那么我的代码有问题吗,或者这就是它的真实情况? 这是我的 C++ 代码:
clock_t tStart = clock();
std::ofstream myfile;
myfile.open("log.txt");
std::string pi;
int limit = 50;
for (int i = 0; i < limit; i++)
for (int j = 0; j < limit; j++)
for (int k = 0; k < limit; k++)
double val = sin(i *i + j *j + k *k);
pi = std::to_string(val);
myfile << pi<<"\n";
myfile.close();
printf("Time taken: %.2fs\n", (double)(clock() - tStart) / CLOCKS_PER_SEC);
getchar();
return 0;
这是我的 C# 代码:
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
string path = @"c:\log.txt";
int limit = 50;
for (int i = 0; i < limit; i++)
for (int j = 0; j < limit; j++)
for (int k = 0; k < limit; k++)
double val = Math.Sin(i *i + j *j + k *k);
using (StreamWriter sw = File.AppendText(path))
sw.WriteLine(val.ToString("F6"));
stopwatch.Stop();
Console.Write(stopwatch.ElapsedMilliseconds);
Console.ReadKey(true);
我的操作系统是 Win7 64 位。 提前感谢您的宝贵时间。
@EDIT:为什么要改变 双倍 val = Math.Sin(i *i + j *j + k *k); 到 双倍 val = Math.Sin(i^2 + j^2 + k^2); 在 C# 中,产生完全不同的答案?
【问题讨论】:
请注意,您正在循环内打开文件 - 与您的 C++ 版本不同。 哇,是的,你是对的。我改变了它,现在 C# 的结果是 44 毫秒,这令人难以置信。那么现在 C++ 出了什么问题呢? @M0HS3N 你确定你在编译时启用了优化? 您正在以调试模式或发布模式运行代码 我删除了 std::string 现在好多了:700 毫秒。在发布模式下,它是 160 毫秒,这要好得多,但仍然比 C# 的 44 毫秒慢。我没有为 C++ 和 C# 做任何优化。 【参考方案1】:for (int j = 0; j < limit; j++)
for (int k = 0; k < limit; k++)
using (StreamWriter sw = File.AppendText(path))
//...
您的结果并不令人惊讶 - 您正在打开文件并在每次迭代时创建和处理 StreamWriter
。您应该创建一次:
using (StreamWriter sw = File.AppendText(path))
for (int j = 0; j < limit; j++)
for (int k = 0; k < limit; k++)
//...
【讨论】:
谢谢,我已经更正了这个问题,现在 C# 的结果是 44 毫秒,这很棒。那么现在我的 C++ 代码出了什么问题? @M0HS3N 不要使用 std::to_string, myfile 我删除了 std::string 现在好多了:700 毫秒。在发布模式下,它是 160 毫秒,这要好得多,但仍然比 C# 的 44 毫秒慢。还有其他想法吗? @M0HS3N 试试 C 风格的 I/O,这样会更快。【参考方案2】:您的测试中最大的不同在于,对于 C++ 测试,您在循环外打开和关闭文件,这意味着它只发生 1 次。
在您的 C# 测试中,您将打开文件,执行文件搜索到最后,然后在每次迭代时关闭它。这将耗费大量时间。
您应该将 Streamwriter 的 Creation 移到循环上方,然后在退出循环后关闭它。
我指的是代码
using (StreamWriter sw = File.AppendText(path))
sw.WriteLine(val.ToString("F6"));
【讨论】:
以上是关于C++ 和 C# 速度测试 - 奇怪的结果的主要内容,如果未能解决你的问题,请参考以下文章
比较 c#、c++ 和 java 的性能(c# 的奇怪行为)