2013-02-20 2 views
1

과 비교하여 왜 느린 지 최근에 우리는 100,000 개 이상의 xml 파일이 있고 그 중 모두가 xml의 특정 데이터 수정이 필요한 요구 사항이있었습니다. 간단한 perl 명령은 작업을 수행하지만 파일이 위치한 시스템에는 perl이 설치되어 있지 않습니다. 따라서 나는 작은 C# 코드를 작성하여 작업을 수행했습니다.이 C++ 코드가 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# 버전보다 훨씬 빠르지 않은 것으로 나타났습니다. In은 두 버전 모두 sevaral times을 실행했습니다. 사실, 실행 중 일부는 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"; 
} 
+5

왜 다른 코드를 기대합니까? –

+0

어떻게 C++ 코드를 컴파일 했습니까? – jogojapan

+0

@jogojapan, 출시 빌드. – Jagannath

답변

3

는 C#을 사용하면 같은 반사와 같은 특정 느린 기능을 사용하지 않는 모든 한 느린되지 않습니다 버그 수정이 아니라 성능 및 로직 최적화에 더 많은 시간을 투자해야합니다. 즉, 더 빨리 끝나야합니다. ...

일반적으로 C# 코드에서 좀 더 일반적인 라이브러리를 사용하는 것 외에는 일반적으로 잘 작성되고 최적화됩니다 MS devs - C++ 코드에서 자신의 함수를 롤백하는 것과 비교하면 ..

+2

C#이나 C++이나 네이티브 컴파일 된 다른 오버 헤드는 일반적으로 JIT 일리노이 주 코드로 변환하는 일이 일어나고, 권투 등의 속도를 늦출 수있는 여러 가지 일들이 있습니다. 생산성 논쟁은 거의 무의미한 것입니다 ... 사람들이 가장 잘 아는 코드이므로 C++로 코딩하는 C++ 프로그래머는 C++로 코딩하는 C++ 프로그래머보다 생산성이 떨어집니다. 그것은 모두 친척입니다. C#의 좋은 코드는 C++의 나쁜 코드를 이길 수 있으며 반대의 경우도 마찬가지입니다. – Corey

+1

이것은 너무 일반적이며 질문에 대한 적절한 답변이 아닙니다. 생산성은 한 가지 코드가 다른 코드보다 빠르게 실행되는 이유에 대해 묻는 질문과는 아무런 관련이 없습니다. –

7

너무 적은 작업으로 많은 파일을 가지고있는 것 같습니다 그들에, 그래서 병목 현상의 주요 디스크 여기에 IO를 완료. 각 파일에 대해 복잡하고 CPU 소모적 인 작업이 있었다면 C++ 버전을 더 빨리 수행 할 수 있었지만 작은 작업에서는 IO가 문제이므로 관련이 없습니다

0

'컴파일'할 때 '컴파일러'는 중간 언어를 생성합니다 코드 (MSIL)를 실행하면이 코드가 dotnet 프레임 워크의 JIT 컴파일러에서 런타임에 컴파일되어 원시 코드로 변환됩니다. JIT 컴파일 코드는 코드를 실행하는 환경에 고도로 최적화되어 있습니다. 이것은 각 함수에 대해 한 번만 발생하며 함수가 원시 코드로 컴파일되면 응용 프로그램이 종료 될 때까지 다시 사용됩니다. 따라서 반복적으로 호출되는 함수가 하나있는 경우 JIT 생성 및 최적화 된 코드가 일반적으로 컴파일 된 C++ 코드보다 성능이 뛰어날 수 있습니다