为什么这个C ++代码比C#variant更慢

时间:2013-02-20 05:42:20

标签: c# c++ ppl

最近,我们要求有超过100,000个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() << " secs\n";
}

3 个答案:

答案 0 :(得分:7)

好像你有很多文件,他们的工作太少,所以主要的瓶颈就是磁盘IO。如果你对每个文件都有一些复杂且耗费CPU的任务,那么你可以更快地使用C ++版本,但是对于小任务来说,这是无关紧要的,因为IO是问题

答案 1 :(得分:3)

尽管有些人认为,只要你不使用某些慢速功能(如反射),c#就不会很慢 - 事实上,人们最终编码速度更快,而且隐藏的错误更少,所以有更多时间花在优化性能和逻辑上,而不是修复错误,这意味着最终会更快......

除了你在C#代码中使用更常见的库,这些库通常由MS开发人员编写和优化 - 与必须在c ++代码中滚动自己的函数相比..

答案 2 :(得分:0)

当你'编译'C​​#代码时,'编译器'会生成中间语言代码(MSIL),然后这个代码在运行时由dotnet框架的JIT编译器编译为本机代码。 JIT编译的代码在您执行代码的环境中进行了高度优化。对于每个函数,这只发生一次,并且一旦将函数编译为本机代码,它将被重用,直到应用程序终止。因此,如果你有一个被反复调用的函数,JIT生成和优化的代码可能会胜过一般编译的C ++代码

相关问题