为什么这个C++代码比C#变体慢
why this C++ code is slower compared to C# variant
最近,我们有一个需求,其中有超过100000个xml文件,所有这些文件都需要修改xml中的特定数据。简单的perl命令可以完成这项工作,但文件所在的机器上没有安装perl。因此,我编写了一个小的C#代码来完成这项工作。
private static void ModifyXML(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
string path = @args[0];
string opath = @args[1];
string token = "value_date="20121130"";
string target = "value_date="20121019"";
Parallel.ForEach(Directory.EnumerateFiles(path), (file) =>
{
StringBuilder sb = new StringBuilder(File.ReadAllText(file));
sb.Remove(0, 55);
sb.Replace(token, target);
var filename = file.Split(new char[] { '' }).Last();
File.WriteAllText(string.Format("{0}\{1}", opath, filename), sb.ToString());
});
TimeSpan ts = sw.Elapsed;
Console.WriteLine("Took {0} secs", ts.TotalSeconds);
}
我决定实现C++版本。事实证明,C++版本并没有明显快于C#版本。这两个版本都运行了好几次。事实上,在某些运行过程中,它的速度与C#版本一样快。
对于C#,我使用.NET 4.0,而对于C++,它是VC10。
void FileHandling(std::string src, std::string dest)
{
namespace fs = boost::filesystem;
auto start = boost::chrono::system_clock::now();
string token = "value_date="20121130"";
string target = "value_date="20121019"";
fs::directory_iterator end_iter;
fs::directory_iterator dir_itr(src);
vector<fs::path> files;
files.insert(files.end(), dir_itr, end_iter);
string dest_path = dest + "\";
parallel_for_each(files.begin(), files.end(), [=](const fs::path& filepath)
{
ifstream inpfile (filepath.generic_string());
string line;
line.insert(line.end(), istreambuf_iterator<char>(inpfile), istreambuf_iterator<char>());
line.erase(0, 55);
auto index = line.find(token, 0);
if (index != string::npos)
{
line.replace(index, token.size(), target);
}
ofstream outfile(dest_path + filepath.filename().generic_string());
outfile << line;
});
boost::chrono::duration<double> finish = boost::chrono::system_clock::now() - start;
std::cout << "Took " << finish.count() << " secsn";
}
似乎有很多文件所做的工作太少,所以这里的主要瓶颈是磁盘IO。如果每个文件都有一些复杂且消耗CPU的任务,那么C++版本可以更快,但对于小任务,这是无关紧要的,因为IO是问题
尽管有些人认为,只要你不使用某些缓慢的功能(如反射),c#就一点也不慢——事实上,人们最终会更快地编码,并且有更少的模糊错误,所以有更多的时间来优化性能和逻辑,而不是修复错误,这意味着它最终会更快。。。
除此之外,您在C#代码中使用了更常见的库,与必须在C++代码中滚动自己的函数相比,这些库通常由MS开发人员编写和优化得很好。。
当您"编译"C#代码时,"编译器"会生成中间语言代码(MSIL),然后由dotnet框架的JIT编译器在运行时将此代码编译为本机代码。JIT编译的代码根据您执行代码的环境进行了高度优化。每个函数只发生一次这种情况,一旦函数被编译为本机代码,它将被重用,直到应用程序终止。因此,如果您有一个函数被反复调用,JIT生成和优化的代码可能会优于一般编译的C++代码
相关文章:
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 代码在main()中运行,但在函数中出现错误
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 编译包含字符串的代码时遇到问题
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 在Linux for Windows上编译C++代码时出错
- 我的字符计数代码计算错误.为什么
- 孤立代码块在结构中引发异常
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 此代码是否违反一个定义规则
- 为什么我的代码在输出中增加了93天
- 我的简单if-else语句是如何无法访问的代码
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 为什么在这个代码结束循环中没有得到结束
- 在c代码之间共享数据的最佳方式
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值