문제

아니면 이제 다른 방법입니까?

내가 들었던 것에 따르면 C#이 C ++보다 빠른 영역이 있지만, 직접 테스트 할 용기가 없었습니다.

이러한 차이점을 자세히 설명하거나 이에 대한 정보를 얻을 수있는 올바른 장소를 지적 할 수 있다고 생각했습니다.

도움이 되었습니까?

해결책

JIT가있는 C# 또는 Java와 같은 바이트 코드 기반 언어가 C ++ 코드만큼 빠를 수없는 엄격한 이유는 없습니다. 그러나 C ++ 코드는 오랫동안 상당히 빠르 었으며 오늘날에는 여전히 많은 경우에도 여전히 있습니다. 이는 주로 고급 JIT 최적화가 구현하기가 복잡하기 때문이며, 정말 멋진 것은 지금 만 도착하고 있습니다.

따라서 많은 경우 C ++가 더 빠릅니다. 그러나 이것은 답의 일부일뿐입니다. C ++가 실제로 빠른 경우, 전문가 프로그래머는 코드에서 지옥을 철저히 최적화 한 프로그램입니다. 이것은 시간이 많이 걸리는 것 (그리고 비싸기 때문에) 일뿐 만 아니라 일반적으로 과도하게 최적화로 인한 오류로 이어집니다.

반면에 해석 된 언어로 된 코드는 나중에 런타임 (.NET CLR 또는 Java VM)의 나중 버전에서 더 빠르게 작동합니다. 그리고 Pointers가있는 언어에서는 불가능한 JIT 컴파일러가 할 수있는 유용한 최적화가 많이 있습니다. 또한 일부는 쓰레기 수집이 일반적으로 수동 메모리 관리만큼 빠르거나 빠르야한다고 주장합니다. 일반적으로 C ++ 또는 C 에서이 모든 것을 구현하고 달성 할 수 있지만 훨씬 더 복잡하고 오류가 발생하기 쉽습니다.

도널드 크 누스 (Donald Knuth)가 말했듯이, "조기 최적화는 모든 악의 근본입니다". 애플리케이션이 주로 성능 임계 산술로 구성되고 병목 현상이 될 것이라는 점을 확실히 알고 있다면 C ++에서는 확실히 더 빠를 것이며 C ++가 다른 사람과 충돌하지 않을 것이라고 확신합니다. 요구 사항, C ++로 이동하십시오. 다른 경우에, 먼저 당신에게 가장 적합한 언어로 애플리케이션을 올바르게 구현하는 데 집중 한 다음 너무 느리게 실행되면 성능 병목 현상을 찾은 다음 코드를 최적화하는 방법에 대해 생각해보십시오. 최악의 경우 외부 기능 인터페이스를 통해 C 코드를 호출해야 할 수도 있으므로 여전히 하위 수준의 언어로 중요한 부품을 작성할 수 있습니다.

올바른 프로그램을 최적화하는 것은 비교적 쉽지만 최적화 된 프로그램을 수정하기가 훨씬 어렵다는 점을 명심하십시오.

실제 속도의 비율을 제공하는 것은 불가능하며 코드에 따라 크게 달라집니다. 대부분의 경우 프로그래밍 언어 구현은 병목 현상조차 아닙니다. 벤치 마크를 취하십시오 http://benchmarksgame.alioth.debian.org/ 이러한 회의론은 크게 테스트 된 산술 코드로, 코드와 전혀 유사하지 않을 가능성이 높습니다.

다른 팁

C#이 더 빠르지는 않지만 더 빠릅니다. 그것이 내가하는 일에 가장 중요한 척도입니다. :)

5 개의 오렌지가 더 빠릅니다. 또는 오히려 : (올바른) 담요 대답이 없을 수 있습니다. C ++는 정적으로 컴파일 된 언어 (그러나 프로필 가이드 최적화도 있습니다), C# Runs Ading Ading Abids a JIT 컴파일러입니다. "얼마나 빠른"와 같은 질문에 대답 할 수없는 많은 차이점이 있습니다.

나는이 질문에 대한 대답의 일부로 동의하지 않는 것으로 시작할 것입니다.

Jitte Code가 올바르게 최적화 된 C ++ (또는 런타임 오버 헤드가없는 기타 언어) 프로그램보다 느리게 실행되는 많은 이유가 있습니다. 포함:

  • 런타임에 JITTING 코드에 소비 된 컴퓨팅주기는 정의상 프로그램 실행에 사용할 수 없습니다.

  • 지터의 핫 경로는 CPU의 명령 및 데이터 캐시에 대한 코드와 경쟁합니다. 우리는 캐시가 성능에있어서 지배적이라는 것을 알고 있으며 C ++와 같은 모국어는 정의상 이러한 유형의 경합이 없다는 것을 알고 있습니다.

  • 런타임 최적화기의 시간 예산은 반드시입니다 많이 컴파일 타임 옵티마이저보다 더 제한적입니다 (다른 의견 제시자가 지적했듯이)

결론 : 궁극적으로, 당신 ~ 할 것이다 C#에서 할 수있는 것보다 C ++에서 더 빠른 구현을 만들 수 있습니다..

이제 그 말로 얼마나 빠릅니다 작업, 문제 도메인, 하드웨어, 구현 품질 및 기타 여러 요인과 같은 변수가 너무 많기 때문에 실제로 정량화 할 수 없습니다. 시나리오에서 실행을 실행하여 성능 차이를 결정한 다음 추가 노력과 복잡성의 가치가 있는지 결정합니다.

이것은 매우 길고 복잡한 주제이지만 C#의 런타임 최적화기가 우수하다는 완전성을 위해 언급 할 가치가 있으며 컴파일 타임으로 C ++로 간단히 사용할 수없는 런타임에서 특정 동적 최적화를 수행 할 수 있습니다 (). 정적) 최적화기. 이에도 불구하고, 이점은 일반적으로 기본 응용 프로그램의 법원에서 여전히 깊이 이점이지만 동적 최적화는 "의 이유입니다."거의 확실히 "위의 예선.

--

상대적인 성과 측면에서, 나는 다른 답변에서 본 수치와 토론에 의해 방해를 받았다.

이러한 벤치 마크의 문제의 큰 부분은 C#을 작성하는 것처럼 C ++ 코드를 작성할 수 없으며 대표적인 결과를 얻을 것으로 예상됩니다 (예 : C ++에서 수천 개의 메모리 할당을 수행하면 끔찍한 숫자를 줄 것입니다).

대신, 나는 약간 더 관용적 인 C ++ 코드를 작성했으며 제공된 C# 코드 @Wiory와 비교했습니다. C ++ 코드에 대한 두 가지 주요 변경 사항은 다음과 같습니다.

1) 중고 벡터 :: 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);
}

런타임 (릴리스) : 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);
}

런타임 (릴리스) : init : 398µs (예, 마이크로 초), 채우기 : 152ms

총 실행 시간 : C#: 289ms, C ++ 152ms (대략 90% 더 빠릅니다)

관찰

  • C# 구현을 동일한 1D 배열 구현으로 변경하면 Init : 40ms, Fill : 171ms, 총 : 211ms (211ms)C ++는 여전히 거의 40% 더 빠릅니다).

  • C ++로 "빠른"코드를 설계하고 작성하는 것이 훨씬 어렵습니다.

  • C ++에서 성능이 저하되는 것은 놀랍게도 쉽게 쉽게 얻을 수 있습니다. 우리는 예약되지 않은 벡터 성능으로 그것을 보았습니다. 그리고 이와 같은 함정이 많이 있습니다.

  • C#의 성능은 런타임에서 진행중인 모든 것을 고려할 때 다소 놀랍습니다. 그리고 그 성능은 비교적 쉽게 액세스 할 수 있습니다.

  • C ++ 및 C#의 성능을 비교하는 더 많은 일화 데이터 : https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=gpp&lang2=csharpcore

결론은 C ++가 성능을 훨씬 더 많이 제어 할 수 있다는 것입니다. 포인터를 사용 하시겠습니까? 참조? 스택 메모리? 더미? 동적 다형성 또는 정적 다형성으로 VTable의 런타임 오버 헤드 (템플릿/CRTP를 통해)? C ++에서는 ... ER, 가십시오 솔루션이 문제를 가장 잘 해결하도록 이상적 으로이 모든 선택 (그리고 그 이상)을 스스로 만들 수 있습니다.

위의 사소한 예제에도 성능이 크게 향상되지만 액세스에 더 깊은 투자가 필요하다는 것을 알 수 있습니다.

내 경험에 따르면 (그리고 두 언어 모두에서 많은 일을 해왔습니다), C#의 주요 문제는 C ++에 비해 메모리 소비가 높으며이를 제어 할 수있는 좋은 방법을 찾지 못했습니다. 결국 .net 소프트웨어를 늦추는 것은 메모리 소비였습니다.

또 다른 요소는 JIT 컴파일러가 런타임에 실행되기 때문에 고급 최적화를 수행하는 데 너무 많은 시간을 할애 할 수 없으며 최종 사용자는 너무 많은 시간이 걸리면이를 알 수 있다는 것입니다. 반면에 C ++ 컴파일러는 항상 컴파일 시간에 최적화를 수행해야합니다. 이 요인은 메모리 소비보다 훨씬 덜 중요합니다.

C ++가 여전히 우위를 차지한 한 가지 특정 시나리오 (그리고 앞으로 몇 년 동안)가 컴파일 시간에 다형성 결정을 미리 결정할 수있을 때 발생합니다.

일반적으로 캡슐화와 연기 된 의사 결정은 코드를보다 역동적이고 변화하는 요구 사항에 쉽게 적응하고 프레임 워크로 사용하기 쉽기 때문에 좋은 일입니다. 이것이 C#의 객체 지향 프로그래밍이 매우 생산적이며“일반화”라는 용어에 따라 일반화 될 수있는 이유입니다. 불행히도,이 특정 종류의 일반화는 런타임 비용으로 제공됩니다.

일반적 으로이 비용은 비 지분이지만 가상 메소드 호출과 객체 생성의 오버 헤드가 차이를 만들 수있는 응용 프로그램이 있습니다 (특히 가상 메소드가 메소드 호출과 같은 다른 최적화를 방해하기 때문에). C ++가 템플릿을 사용하여 다른 종류의 일반화를 달성 할 수 있기 때문에 큰 이점이있는 곳입니다. 아니요 런타임에 영향을 미치지 만 반드시 OOP보다 다형성은 아닙니다. 실제로, OOP를 구성하는 모든 메커니즘은 템플릿 기술과 컴파일 시간 해상도 만 사용하여 모델링 될 수 있습니다.

그러한 경우 (그리고 분명히, 그들은 종종 특수 문제 도메인으로 제한됨), C ++는 C# 및 비슷한 언어에 대한 승리입니다.

C ++ (또는 해당 물질의 C)는 데이터 구조를 세밀하게 제어 할 수있게합니다. 비트를 비트로 만들고 싶다면 해당 옵션이 있습니다. 대규모 관리 자바 또는 .NET 앱 (OWB, Visual Studio 2005) Java/.NET 라이브러리의 내부 데이터 구조를 사용하여 수하물을 가지고 다닙니다. 나는 400MB 이상의 RAM을 사용하여 OWB 디자이너 세션을 보았고 큐브에 대한 입찰을 보았습니다. ETL 디자인은 100 년대 MB에 들어가는 것도 있습니다.

예측 가능한 워크로드 (예 : 프로세스를 여러 번 반복하는 대부분의 벤치 마크)에서 JIT는 실질적인 차이가 없을 정도로 충분히 최적화 된 코드를 얻을 수 있습니다.

대규모 응용 프로그램의 IMO 차이는 코드 자체가 사용하는 데이터 구조만큼 JIT가 아닙니다. 애플리케이션이 메모리가 급증하는 경우 효율적인 캐시 사용을 얻을 수 있습니다. 현대 CPU의 캐시 누락은 매우 비쌉니다. C 또는 C ++가 실제로이기는 곳은 CPU 캐시와 함께 잘 작동하도록 데이터 구조 사용을 최적화 할 수있는 곳입니다.

그래픽의 경우 표준 C# 그래픽 클래스는 C/C ++를 통해 액세스 한 GDI보다 느립니다. 나는 이것이 전체 .NET 플랫폼과 더 관련이 없다는 것을 알고 있지만 그래픽은 GDI 교체로 개발자에게 제공되는 것이며, 그 성능은 너무 나쁘기 때문에 그래픽을 감히하지 않을 것입니다. 그것으로.

그래픽 라이브러리가 얼마나 빨리 있는지 확인하는 데 사용하는 간단한 벤치 마크가 있으며, 이는 단순히 창에 임의의 선을 그리는 것입니다. C ++/GDI는 여전히 10000 라인을 사용하는 반면 C#/그래픽은 실시간 1000을 수행하는 데 어려움이 있습니다.

쓰레기 수집은 Java#이 실시간 시스템에 사용할 수없는 주된 이유입니다.

  1. GC는 언제 발생합니까?

  2. 얼마나 걸릴까요?

이것은 비 결정적입니다.

우리는 C#이 성능에서 C ++와 비슷한 지 확인해야했으며 (두 언어 모두 Visual Studio 2005 사용) 그 테스트 프로그램을 작성했습니다. 쓰레기 수집이없고 언어 (프레임 워크가 아님) 만 고려하는 것은 기본적으로 C ++와 동일한 성능을 가지고 있음이 밝혀졌습니다. 메모리 할당은 C ++보다 C#에서 더 빠르며 C#은 캐시 라인 경계를 넘어서 데이터 크기가 증가 할 때 결정론에서 약간의 우위를 가짐입니다. 그러나이 모든 것이 결국 지불되어야했으며 쓰레기 수집으로 인해 C#에 대한 비 결정적 성능 히트의 형태로 막대한 비용이 있습니다.

평소와 같이 응용 프로그램에 따라 다릅니다. C#이 무시할 수 없을 정도로 느리게 진행되는 경우가 있으며 C ++가 5 ~ 10 배 더 빠른 경우, 특히 작업이 쉽게 심을 수있는 경우.

나는 그것이 당신이 요구했던 것이 아니라는 것을 알고 있지만 C#은 종종 더 빠릅니다. 쓰다 C ++보다 상업 환경에서 큰 보너스입니다.

C/C ++는 큰 배열 또는 어레이에 대한 중장비/반복이있는 프로그램에서 훨씬 더 잘 수행 할 수 있습니다 (모든 크기). 무거운 배열 작업이 거의 모든 그래픽 작업의 기초가되기 때문에 그래픽이 일반적으로 C/C ++에서 훨씬 빠른 이유입니다. .NET은 모든 안전 점검으로 인해 배열 인덱싱 작업이 악명 높으며, 이는 다차원 배열에 특히 해당됩니다 (예, 직사각형 C# 배열이 Jagged C# 배열보다 느리게 느리게).

C/C ++의 보너스는 포인터를 직접 고수하고 부스트를 피하면 가장 두드러집니다. std::vector 및 기타 고급 컨테이너뿐만 아니라 inline 가능한 모든 작은 기능. 가능할 때마다 구식 배열을 사용하십시오. 예, 높은 수준의 컨테이너를 피할 때 Java 또는 C#에서 한 것과 동일한 작업을 수행하려면 더 많은 코드 라인이 필요합니다. 동적 크기의 배열이 필요한 경우, 당신은 당신의 쌍을 기억하면됩니다 new T[] 해당 delete[] 진술 (또는 사용 std::unique_ptr) - 추가 속도의 가격은보다 신중하게 코딩해야한다는 것입니다. 그러나 대신하여 관리되는 메모리 / 가비지 수집기의 오버 헤드를 제거하게됩니다. 이는 Java 및 .NET 모두에서 객체 지향적 인 프로그램의 실행 시간과 대규모 관리자 모두가 쉽게 20% 이상이 될 수 있습니다. 메모리 어레이 인덱싱 비용. C ++ 앱은 특정 경우 특정 경우 일부 멋진 컴파일러 스위치의 혜택을 누릴 수 있습니다.

저는 C, C ++, Java 및 C#의 전문가 프로그래머입니다. 나는 최근에 3 개 언어에서 정확히 동일한 알고리즘 프로그램을 구현할 드문 경우가있었습니다. 이 프로그램에는 많은 수학 및 다차원 배열 작업이있었습니다. 나는 이것을 3 개 언어로 모두 최적화했습니다. 결과는 덜 엄격한 비교에서 일반적으로 보는 것의 전형적인 것이 었습니다. Java는 C#보다 약 1.3 배 빠르며 (대부분의 JVM은 CLR보다 최적화되어 있음) C ++ RAW 포인터 버전은 C#보다 약 2.1 배 더 빠릅니다. C# 프로그램은 안전한 코드 만 사용했음을 주목하십시오. 사용하기 전에 C ++로 코딩 할 수 있다는 의견입니다. unsafe 예어.

누구든지 내가 C#에 대해 무언가가 있다고 생각하지 않도록 C#이 아마도 내가 가장 좋아하는 언어라고 말함으로써 닫을 것입니다. 지금까지 발생한 가장 논리적이고 직관적이며 빠른 개발 언어입니다. C#에서 모든 프로토 타이핑을합니다. C# 언어는 Java에 비해 많은 작고 미묘한 이점을 가지고 있습니다 (예, Microsoft는 게임에 늦게 들어 와서 Java를 복사함으로써 많은 Java의 단점을 고칠 기회가 있다는 것을 알고 있습니다). 자바에 건배 Calendar 누구든지 수업? Microsoft가 CLR을 최적화하고 .NET 지터를 최적화하기 위해 실제로 노력하면 C#이 심각하게 인수 할 수 있습니다. 솔직히 그들이 아직도 C# 언어로 너무 많은 일을했는데, 왜 치열한 컴파일러 최적화로 그것을 따르지 않겠습니까? 어쩌면 우리 모두가 구걸한다면.

> 내가 들었던 것에서 ...

당신의 어려움은 당신이 들었던 것이 신뢰할 수 있는지를 결정하는 데있어서,이 사이트의 답변을 평가하려고 할 때 그 어려움은 반복 될 것입니다.

사람들이 여기서 말하는 것들이 원래 들었던 것보다 다소 신뢰할 수 있는지 어떻게 결정할 것인가?

한 가지 방법은 요청하는 것입니다 증거.

누군가가 "C#이 C ++보다 빠른 영역이 있습니다"라고 주장하면 그들에게 묻다 그들은 그렇게 말합니다, 그들에게 측정 값을 보여달라고 요청하고, 프로그램을 보여달라고 요청하십시오. 때때로 그들은 단순히 실수를했을 것입니다. 때때로 당신은 그들이 진실로 보여줄 수있는 것을 공유하기보다는 의견을 표현하고 있음을 알게 될 것입니다.

종종 정보와 의견이 사람들이 주장하는 것에 혼합 될 것이며, 당신은 어떤 것인지를 정리하고 정리해야합니다. 예를 들어,이 포럼의 답변에서 :

  • "벤치 마크를 가져 가라 http://shootout.alioth.debian.org/이러한 회의론은 크게 테스트 된 산술 코드로, 코드와 전혀 유사하지 않을 가능성이 높습니다. "

    정말로 무엇을 이해하는지 스스로에게 물어보십시오 "이 크게 테스트 된 산술 코드" 그런 다음 저자가 자신의 주장이 사실임을 실제로 보여 주 었는지 스스로에게 물어보십시오.

  • "이것은 개별 프로그램이 얼마나 잘 최적화되었는지에 달려 있기 때문에 다소 쓸모없는 테스트입니다. 나는 이들 중 일부를 4-6 배 이상 높이기 위해 최적화되지 않은 프로그램 간의 비교가 오히려 오히려임을 분명히했습니다. 바보 같은."

    저자가 실제로 그가 "4-6 배 이상 속도를 높이고"관리했는지 알 수 있는지 스스로에게 물어보십시오. 쉬운 주장입니다!

.NET 언어는 C ++ 코드만큼 빠르거나 더 빠를 수 있습니다. 그러나 C ++ 코드는 더 일정한 처리량을 가질 것입니다. .NET 런타임이 일시 중지해야합니다 GC, 일시 정지에 대해 매우 영리하더라도.

따라서 일시 정지없이 빠르게 실행 해야하는 코드가 있으면 .NET은 대기 시간을 소개합니다. 어느 시점에서, 런타임 GC에 매우주의를 기울이더라도.

'부패하게 평행 한'문제의 경우 C ++에서 Intel TBB 및 OpenMP를 사용할 때 C# 및 TPL에서 수행 된 유사한 (순수한 수학) 문제에 비해 약 10 배의 성능 증가를 관찰했습니다. Simd는 C#이 경쟁 할 수없는 영역이지만 TPL에 상당한 오버 헤드가 있다는 인상을 받았습니다.

즉, 나는 성능 약정 작업에 C ++ 만 사용하여 멀티 스테일을하고 결과를 빠르게 얻을 수 있다는 것을 알고 있습니다. 다른 모든 것에 대해 C# (그리고 때로는 f#)은 괜찮습니다.

진정한 결정적인 답변이없는 매우 모호한 질문입니다.

예를 들어; 성능이 훨씬 더 좋기 때문에 C#보다 C ++로 생성 된 3D 게임을 재생하고 싶습니다. (그리고 나는 XNA 등을 알고 있지만 실제 일에 가까운 곳은 없습니다).

반면에, 앞서 언급 한 바와 같이; 당신은 당신이 원하는 것을 신속하게 할 수있는 언어로 개발하고 필요한 경우 최적화해야합니다.

In theory, for long running server-type application, a JIT-compiled language can become much faster than a natively compiled counterpart. Since the JIT compiled language is generally first compiled to a fairly low-level intermediate language, you can do a lot of the high-level optimizations right at compile time anyway. The big advantage comes in that the JIT can continue to recompile sections of code on the fly as it gets more and more data on how the application is being used. It can arrange the most common code-paths to allow branch prediction to succeed as often as possible. It can re-arrange separate code blocks that are often called together to keep them both in the cache. It can spend more effort optimizing inner loops.

I doubt that this is done by .NET or any of the JREs, but it was being researched back when I was in university, so it's not unreasonable to think that these sort of things may find their way into the real world at some point soon.

Applications that require intensive memory access eg. image manipulation are usually better off written in unmanaged environment (C++) than managed (C#). Optimized inner loops with pointer arithmetics are much easier to have control of in C++. In C# you might need to resort to unsafe code to even get near the same performance.

I've tested vector in C++ and C# equivalent - List and simple 2d arrays.

I'm using Visual C#/C++ 2010 Express editions. Both projects are simple console applications, I've tested them in standard (no custom settings) release and debug mode. C# lists run faster on my pc, array initialization is also faster in C#, math operations are slower.

I'm using Intel Core2Duo P8600@2.4GHz, C# - .NET 4.0.

I know that vector implementation is different than C# list, but I just wanted to test collections that I would use to store my objects (and being able to use index accessor).

Of course you need to clear memory (let's say for every use of new), but I wanted to keep the code simple.

C++ vector test:

static void TestVector()
{
    clock_t start,finish;
    start=clock();
    vector<vector<double>> myList=vector<vector<double>>();
    int i=0;
    for( i=0; i<500; i++)
    {
        myList.push_back(vector<double>());
        for(int j=0;j<50000;j++)
            myList[i].push_back(j+i);
    }
    finish=clock();
    cout<<(finish-start)<<endl;
    cout<<(double(finish - start)/CLOCKS_PER_SEC);
}

C# list test:

private static void TestVector()
{

    DateTime t1 = System.DateTime.Now;
    List<List<double>> myList = new List<List<double>>();
    int i = 0;
    for (i = 0; i < 500; i++)
    {
        myList.Add(new List<double>());
        for (int j = 0; j < 50000; j++)
            myList[i].Add(j *i);
    }
    DateTime t2 = System.DateTime.Now;
    Console.WriteLine(t2 - t1);
}

C++ - array:

static void TestArray()
{
    cout << "Normal array test:" << endl;
    const int rows = 5000;
    const int columns = 9000;
    clock_t start, finish;

    start = clock();
    double** arr = new double*[rows];
    for (int i = 0; i < rows; i++)
        arr[i] = new double[columns];
    finish = clock();

    cout << (finish - start) << endl;

    start = clock();
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < columns; j++)
            arr[i][j] = i * j;
    finish = clock();

    cout << (finish - start) << endl;
}

C# - array:

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 * j;
    t2 = System.DateTime.Now;

    Console.WriteLine(t2 - t1);

}

Time: (Release/Debug)

C++

  • 600 / 606 ms array init,
  • 200 / 270 ms array fill,
  • 1sec /13sec vector init & fill.

(Yes, 13 seconds, I always have problems with lists/vectors in debug mode.)

C#:

  • 20 / 20 ms array init,
  • 403 / 440 ms array fill,
  • 710 / 742 ms list init & fill.

Well, it depends. 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).

I suppose there are applications written in C# running fast, as well as there are more C++ written apps running fast (well C++ just older... and take UNIX too...)
- the question indeed is - what is that thing, users and developers are complaining about ...
Well, IMHO, in case of C# we have very comfort UI, very nice hierarchy of libraries, and whole interface system of CLI. In case of C++ we have templates, ATL, COM, MFC and whole shebang of alreadyc written and running code like OpenGL, DirectX and so on... Developers complains of indeterminably risen GC calls in case of C# (means program runs fast, and in one second - bang! it's stuck).
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.

I would put it this way: programmers who write faster code, are the ones who are the more informed of what makes current machines go fast, and incidentally they are also the ones who use an appropriate tool that allows for precise low-level and deterministic optimisation techniques. For these reasons, these people are the ones who use C/C++ rather than C#. I would go as far as stating this as a fact.

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

Umm, no.

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?

If I'm not mistaken, C# templates are determined at runtime. This must be slower than compile time templates of C++.

And when you take in all the other compile-time optimizations mentioned by so many others, as well as the lack of safety that does, indeed, mean more speed...

I'd say C++ is the obvious choice in terms of raw speed and minimum memory consumption. But this also translates into more time developing the code and ensuring you aren't leaking memory or causing any null pointer exceptions.

Verdict:

  • C#: Faster development, slower run

  • C++: Slow development, faster run.

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;
}

There are some major differences between C# and C++ on the performance aspect:

  • C# is GC / heap based. The allocation and GC itself is overhead as the non locality of the memory access
  • C++ optimizers have become very good over the years. JIT compilers cannot achieve the same level since they have only limited compilation time and don't see the global scope

Besides that programmer competence plays also a role. I have seen bad C++ code where classes where passed by value as argument all over the place. You can actually make it worse in C++ if you don't pay attention.

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!!!
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top