c# - 哪個好 - c++和c语言的区别




C++比C#快多少? (18)

或者現在是另一種方式?

從我聽說的有一些地方C#證明比C ++更快,但我從來沒有膽量來自己測試它。

想到你們任何一個人都可以詳細解釋這些差異,或者指出我在這方面的信息的正確位置。


.NET語言可以像C ++代碼一樣快,甚至更快, 但是C ++代碼將具有更恆定的吞吐量,因為.NET運行時必須暫停GC ,即使它對於暫停很聰明。

因此,如果你有一些代碼必須一直運行得很快而沒有任何停頓,那麼即使你對運行時GC非常小心,.NET也會在某些時候引入延遲。


C ++(或C就此而言)使您能夠對數據結構進行細粒度的控制。 如果你想咬一口,你有這個選擇。 大型託管的Java或.NET應用程序(OWB, Visual Studio 2005 )使用Java / .NET庫的內部數據結構,隨身攜帶行李。 我已經看到OWB設計者會話使用超過400 MB的RAM和BIDS,以進入100多MB的立方體或ETL設計。

在可預測的工作負載(例如大多數重複某個進程的基準測試)上,JIT可以為您提供足夠優化的代碼,使其沒有實際區別。

國際海事組織在大型應用程序上的差別不在於代碼本身使用的數據結構。 如果應用程序內存很大,則緩存使用效率會降低。 現代CPU上的高速緩存未命中相當昂貴。 在C或C ++真正獲勝的地方,您可以優化數據結構的使用,以便與CPU緩存良好地協作。


C#可能不會更快,但它會讓你/我的速度更快。 這是我所做的最重要的措施。 :)


> After all, the answers have to be somewhere, haven't they? :)

嗯,不。

As several replies noted, the question is under-specified in ways that invite questions in response, not answers. To take just one way:

And then which programs? Which machine? Which OS? Which data set?


Inspired by this, I did a quick test with 60 percent of common instruction needed in most of the programs.

Here's the C# code:

for (int i=0; i<1000; i++)
{
    StreamReader str = new StreamReader("file.csv");
    StreamWriter stw = new StreamWriter("examp.csv");
    string strL = "";
    while((strL = str.ReadLine()) != null)
    {
        ArrayList al = new ArrayList();
        string[] strline = strL.Split(',');
        al.AddRange(strline);
        foreach(string str1 in strline)
        {
            stw.Write(str1 + ",");
        }
        stw.Write("\n");
    }
    str.Close();
    stw.Close();
}

String array and arraylist are used purposely to include those instructions.

Here's the c++ code:

for (int i = 0; i<1000; i++)
{
    std::fstream file("file.csv", ios::in);
    if (!file.is_open())
    {
        std::cout << "File not found!\n";
        return 1;
    }

    ofstream myfile;
    myfile.open ("example.txt");
    std::string csvLine;

    while (std::getline(file, csvLine))
    {
        std::istringstream csvStream(csvLine);
        std::vector csvColumn;
        std::string csvElement;

        while( std::getline(csvStream, csvElement, ‘,’) )
        {
            csvColumn.push_back(csvElement);
        }

        for (std::vector::iterator j = csvColumn.begin(); j != csvColumn.end(); ++j)
        {
            myfile << *j << ", ";
        }

        csvColumn.clear();
        csvElement.clear();
        csvLine.clear();
        myfile << "\n";
    }
    myfile.close();
    file.close();
}

The input file size I used was 40 KB.

And here's the result -

  • C++ code ran in 9 seconds.
  • C# code: 4 seconds!!!

Oh, but this was on Linux... With C# running on Mono ... And C++ with g++.

OK, this is what I got on Windows – Visual Studio 2003 :

  • C# code ran in 9 seconds.
  • C++ code – horrible 370 seconds!!!

It really depends on what you're trying to accomplish in your code. I've heard that it's just stuff of urban legend that there is any performance difference between VB.NET, C# and managed C++. However, I've found, at least in string comparisons, that managed C++ beats the pants off of C#, which in turn beats the pants off of VB.NET.

I've by no means done any exhaustive comparisons in algorithmic complexity between the languages. I'm also just using the default settings in each of the languages. In VB.NET I'm using settings to require declaration of variables, etc. Here is the code I'm using for managed C++: (As you can see, this code is quite simple). I'm running the same in the other languages in Visual Studio 2013 with .NET 4.6.2.

#include "stdafx.h"

using namespace System;
using namespace System::Diagnostics;

bool EqualMe(String^ first, String^ second)
{
    return first->Equals(second);
}
int main(array<String ^> ^args)
{
    Stopwatch^ sw = gcnew Stopwatch();
    sw->Start();
    for (int i = 0; i < 100000; i++)
    {
        EqualMe(L"one", L"two");
    }
    sw->Stop();
    Console::WriteLine(sw->ElapsedTicks);
    return 0;
}

像往常一樣,這取決於應用程序。 有些情況下C#可能會慢得多,其他情況下C ++的速度要快5到10倍,特別是在可以簡單操作SIMD的情況下。


垃圾收集是Java#不能用於實時系統的主要原因。

  1. GC何時會發生?

  2. 這需要多長時間?

這是非確定性的。


它快五個橙子。 或者說:沒有(正確的)一攬子答案。 C ++是一種靜態編譯的語言(但是後來還有配置文件引導優化),C#運行在JIT編譯器的幫助下運行。 有很多不同之處,像“多快”這樣的問題是無法回答的,甚至沒有給出數量級的答案。


對於'尷尬平行'的問題,當在C ++上使用英特爾TBB和OpenMP時,與C#和TPL完成的類似(純數學)問題相比,我觀察到性能提高了大約10倍。 SIMD是C#無法競爭的領域之一,但我也認為TPL具有相當大的開銷。

也就是說,我只使用C ++進行性能關鍵任務,我知道我將能夠快速多線程並獲得結果。 對於其他任何事情,C#(偶爾F#)都很好。


我們必須確定C#在性能上是否與C ++相媲美,並且為此編寫了一些測試程序(對於這兩種語言都使用Visual Studio 2005)。 事實證明,沒有垃圾收集,只考慮語言(不是框架),C#與C ++具有基本相同的性能。 內存分配在C#中比在C ++中快得多,當數據大小超出高速緩存行邊界時,C#在確定性方面略有優勢。 然而,所有這些最終都要付錢,並且由於垃圾收集,C#的非確定性性能命中的形式存在巨大成本。


我將首先不同意這個問題的一部分接受的(並且是高效的)答案,並指出:

實際上,為什麼JITted代碼的運行速度比經過適當優化的C ++(或沒有運行時間開銷的其他語言)程序慢得多,其中包括:

  • 在運行時花費在JITting代碼上的計算週期根據定義不可用於程序執行。

  • JITter中的任何熱路徑將與您的代碼競爭CPU中的指令和數據緩存。 根據定義,我們知道緩存在性能和本地語言(如C ++)中占主導地位,並沒有這種類型的爭用。

  • 運行時優化器的時間預算必然比編譯時優化器的約束更多(正如另一位評論者指出的那樣)

底線:最終,您幾乎可以肯定能夠在C ++中創建比C#更快的實現

現在,就這麼說,實際上無法量化的速度有多快 ,因為變量太多:任務,問題域,硬件,實施質量以及許多其他因素。 您將針對您的場景運行測試,以確定額外的努力和復雜性是否值得。

這是一個非常漫長而復雜的話題,但我覺得值得一提的是,為了完整起見,C#的運行時優化器非常出色,並且能夠在運行時執行某些動態優化,而C ++在其編譯時無法使用它(靜態)優化器。 即使如此,優勢仍然在本地應用程序的法庭中通常很深,但動態優化器是上面給出的“ 幾乎肯定”限定符的原因。

-

就相對錶現而言,我還對其他答案中看到的數字和討論感到不安,所以我認為我會在同一時間內為上述陳述提供一些支持。

這些基準測試的很大一部分問題是,你不能像編寫C#那樣編寫C ++代碼,並希望得到具有代表性的結果(例如,在C ++中執行數千次內存分配會給你帶來可怕的數字)。

相反,我寫了稍微更習慣的C ++代碼,並與@Wiory提供的C#代碼進行了比較。 我對C ++代碼做出的兩個主要更改是:

1)使用了vector :: reserve()

2)將2d數組展平為1d以獲得更好的緩存局部性(連續塊)

C#(.NET 4.6.1)

private static void TestArray()
{
    const int rows = 5000;
    const int columns = 9000;
    DateTime t1 = System.DateTime.Now;
    double[][] arr = new double[rows][];
    for (int i = 0; i < rows; i++)
        arr[i] = new double[columns];
    DateTime t2 = System.DateTime.Now;

    Console.WriteLine(t2 - t1);

    t1 = System.DateTime.Now;
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < columns; j++)
            arr[i][j] = i;
    t2 = System.DateTime.Now;

    Console.WriteLine(t2 - t1);
}

運行時間(Release):Init:124ms,填充:165ms

C ++ 14(Clang v3.8 / C2)

#include <iostream>
#include <vector>

auto TestSuite::ColMajorArray()
{
    constexpr size_t ROWS = 5000;
    constexpr size_t COLS = 9000;

    auto initStart = std::chrono::steady_clock::now();

    auto arr = std::vector<double>();
    arr.reserve(ROWS * COLS);

    auto initFinish = std::chrono::steady_clock::now();
    auto initTime = std::chrono::duration_cast<std::chrono::microseconds>(initFinish - initStart);

    auto fillStart = std::chrono::steady_clock::now();

    for(auto i = 0, r = 0; r < ROWS; ++r)
    {
        for (auto c = 0; c < COLS; ++c)
        {
            arr[i++] = static_cast<double>(r * c);
        }
    }

    auto fillFinish = std::chrono::steady_clock::now();
    auto fillTime = std::chrono::duration_cast<std::chrono::milliseconds>(fillFinish - fillStart);

    return std::make_pair(initTime, fillTime);
}

運行時間(釋放):初始化:398μs(是,這是微秒),填充:152ms

總運行時間:C#:289ms,C ++ 152ms(大約快90%)

意見

底線是C ++讓你對性能有更多的控制。 你想用指針嗎? 參考? 堆棧內存? 堆? 動態多態或消除具有靜態多態性的vtable的運行時間開銷(通過模板/ CRTP)? 在C ++中,你必須......呃, 自己做出所有這些選擇(更多),理想的是讓你的解決方案最好地解決你正在處理的問題。

問問自己,你是否真的想要或需要這種控制,因為即使是上面這個微不足道的例子,你也可以看到雖然性能有顯著的提高,但它需要更深入的訪問投資。


我會這樣說:編寫更快代碼的程序員是那些更了解當前機器運行速度的人,而且他們也是那些使用適當工具的人,他們允許精確的低級和確定性優化技術。 出於這些原因,這些人是使用C / C ++而不是C#的人。 我甚至會說這是一個事實。


我猜應用C#編寫的應用程序運行速度很快,而且還有更多的C ++編寫的應用程序運行速度很快(C ++只是老一點......而且還要使用UNIX ...)
- 問題的確是 - 用戶和開發人員都在抱怨...
那麼,恕我直言,在C#的情況下,我們有非常舒適的用戶界面,非常好的層次結構庫,以及完整的CLI界面系統。 在C ++的情況下,我們有模板,ATL,COM,MFC以及像OpenGL,DirectX等已經編寫和運行的代碼的完整版本......開發人員抱怨在C#的情況下GC調用會不確定地上升(這意味著程序運行速度很快,而且在一秒鐘內 - 砰!它卡住了)。
To write code in C# very simple and fast (not to forget that also increase chance of errors. In case of C++, developers complains of memory leaks, - means crushes, calls between DLLs, as well as of "DLL hell" - problem with support and replacement libraries by newer ones...
I think more skill you'll have in the programming language, the more quality (and speed) will characterize your software.


根據我的經驗(我已經在這兩種語言中工作過很多),與C ++相比,C ++的主要問題是內存消耗大,並且我還沒有找到控制它的好方法。 內存消耗最終會減慢.NET軟件的速度。

另一個因素是JIT編譯器不能承擔太多時間來執行高級優化,因為它在運行時運行,並且如果最終用戶花費太多時間,它會注意到它。 另一方面,C ++編譯器一直需要在編譯時進行優化。 這個因素比內存消耗少得多,恕我直言。


沒有嚴格的原因,為什麼像C#或Java這樣的基於字節碼的語言具有JIT不能像C ++代碼那麼快。 然而,C ++代碼在很長一段時間裡過去顯得更快,而今天在很多情況下也是如此。 這主要是由於更高級的JIT優化實施起來很複雜,而且非常酷的只是剛剛到達。

所以C ++在很多情況下速度更快。 但這只是答案的一部分。 C ++實際上更快的情況是高度優化的程序,專家程序員徹底優化了代碼。 這不僅非常耗時(並且因此很昂貴),而且由於過度優化而通常導致錯誤。

另一方面,解釋型語言中的代碼在運行時(.NET CLR或Java VM)的後續版本中速度會更快,而無需執行任何操作。 有很多有用的優化JIT編譯器可以做到這一點,在指針語言中是不可能的。 另外,有人認為垃圾回收通常應該像手動內存管理一樣快或者更快,並且在很多情況下是這樣。 通常你可以在C ++或C中實現和實現所有這些,但它會變得更加複雜和容易出錯。

正如Donald Knuth所說,“不成熟的優化是一切罪惡的根源”。 如果您確實知道您的應用程序將主要包含非常高性能的關鍵算術,並且它將成為瓶頸,並且在C ++中肯定會更快,並且您確信C ++不會與其他人發生衝突要求,去C ++。 在任何其他情況下,請專注於首先以最適合您的任何語言正確實施您的應用程序,然後在運行速度過慢時發現性能瓶頸,然後考慮如何優化代碼。 在最糟糕的情況下,您可能需要通過外部函數接口調用C代碼,因此您仍然可以使用低級語言編寫關鍵部分。

請記住,優化正確的程序相對容易,但更難以糾正優化的程序。

提供速度優勢的實際百分比是不可能的,它主要取決於您的代碼。 在許多情況下,編程語言的實現甚至不是瓶頸。 請參考http://benchmarksgame.alioth.debian.org/上的基準,並帶有很多懷疑,因為它們主要測試算術代碼,它很可能與您的代碼很不相似。


這得看情況。 If the byte-code is translated into machine-code (and not just JIT) (I mean if you execute the program) and if your program uses many allocations/deallocations it could be faster because the GC algorithm just need one pass (theoretically) through the whole memory once, but normal malloc/realloc/free C/C++ calls causes an overhead on every call (call-overhead, data-structure overhead, cache misses ;) ).

So it is theoretically possible (also for other GC languages).

I don't really see the extreme disadvantage of not to be able to use metaprogramming with C# for the most applications, because the most programmers don't use it anyway.

Another big advantage is that the SQL, like the LINQ "extension", provides opportunities for the compiler to optimize calls to databases (in other words, the compiler could compile the whole LINQ to one "blob" binary where the called functions are inlined or for your use optimized, but I'm speculating here).


這是一個非常模糊的問題,沒有真正的明確答案。

例如; 我寧願玩C ++創建的3D遊戲,因為它的性能肯定要好很多。 (而且我知道XNA等,但它沒有辦法接近真實的東西)。

另一方面,如前所述; 你應該用一種語言進行開發,讓你快速做到自己想做的事情,然後在必要時進行優化。





benchmarking