아니면 지금 다른 방향입니까?
내가 들었던 것에서 C #이 C ++보다 빠르다는 영역이 있지만 직접 테스트 할 용기는 없었습니다.
이러한 차이점을 자세히 설명하거나 이에 대한 정보를 얻을 수있는 적절한 장소를 알려줄 수 있다고 생각했습니다.
아니면 지금 다른 방향입니까?
내가 들었던 것에서 C #이 C ++보다 빠르다는 영역이 있지만 직접 테스트 할 용기는 없었습니다.
이러한 차이점을 자세히 설명하거나 이에 대한 정보를 얻을 수있는 적절한 장소를 알려줄 수 있다고 생각했습니다.
답변:
JIT가있는 C # 또는 Java와 같은 바이트 코드 기반 언어가 C ++ 코드만큼 빠를 수없는 확실한 이유는 없습니다. 그러나 C ++ 코드는 오랫동안 훨씬 더 빨랐으며 오늘날에도 여전히 많은 경우가 있습니다. 이는 주로 고급 JIT 최적화가 구현하기가 복잡하기 때문이며 실제로 멋진 기능은 지금 막 도착했습니다.
따라서 많은 경우 C ++이 더 빠릅니다. 그러나 이것은 답의 일부일뿐입니다. C ++이 실제로 더 빠른 경우는 고도로 최적화 된 프로그램이며, 전문 프로그래머는 코드에서 지옥을 철저히 최적화합니다. 이 작업은 시간이 많이 걸리고 비용이 많이들뿐만 아니라 지나치게 최적화되어 오류가 발생하기도합니다.
반면, 해석 된 언어의 코드는 아무 것도하지 않고도 이후 버전의 런타임 (.NET CLR 또는 Java VM)에서 더 빨라집니다. 그리고 JIT 컴파일러가 포인터를 사용하는 언어에서는 불가능한 유용한 최적화가 많이 있습니다. 또한 일부는 가비지 수집이 일반적으로 수동 메모리 관리만큼 빠르거나 빠르지 않아야한다고 주장합니다. 일반적으로 C ++ 또는 C에서이 모든 것을 구현하고 달성 할 수 있지만 훨씬 더 복잡하고 오류가 발생하기 쉽습니다.
도널드 크 누스 (Donald Knuth)는“조기 최적화는 모든 악의 근원”이라고 말했다. 응용 프로그램이 주로 성능이 매우 중요한 산술로 구성되고 병목 현상이 발생하고 C ++에서는 더 빨라질 것이라는 것을 확실히 알고 있다면 C ++이 다른 응용 프로그램과 충돌하지 않을 것입니다. 요구 사항은 C ++로 이동하십시오. 다른 경우에는 먼저 가장 적합한 언어로 응용 프로그램을 올바르게 구현하는 데 집중 한 다음 너무 느리게 실행되면 성능 병목 현상을 찾은 다음 코드를 최적화하는 방법에 대해 생각하십시오. 최악의 경우 외부 함수 인터페이스를 통해 C 코드를 호출해야 할 수 있으므로 하위 언어로 중요한 부분을 작성할 수 있습니다.
올바른 프로그램을 최적화하는 것은 상대적으로 쉽지만 최적화 된 프로그램을 수정하는 것이 훨씬 어렵다는 점에 유의하십시오.
속도 이점의 실제 비율을 제공하는 것은 불가능하며 코드에 따라 크게 다릅니다. 대부분의 경우 프로그래밍 언어 구현은 병목 현상이 아닙니다. http : //benchmarksgame.alioth.debian .
C #은 빠르지는 않지만 귀하 / ME를 더 빠르게 만듭니다. 그것이 내가하는 일에 대한 가장 중요한 척도입니다. :)
오렌지 5 개가 더 빠릅니다. 또는 오히려 : (올바른) 담요 답변이 없을 수 있습니다. C ++는 정적으로 컴파일 된 언어입니다 (그러나 프로파일 가이드 최적화도 있습니다). C #은 JIT 컴파일러의 도움을받습니다. “얼마나 더 빠른가”와 같은 질문에 대해 질서를내는 것조차도 대답 할 수없는 많은 차이가 있습니다.
나는 다음과 같이 진술함으로써이 질문에 대해 받아 들여지고 잘 찬성 된 답변의 일부에 동의하지 않는 것으로 시작할 것입니다.
실제로 JITted 코드가 올바르게 최적화 된 C ++ (또는 런타임 오버 헤드가없는 다른 언어) 프로그램보다 느리게 실행되는 이유는 다음과 같습니다.
런타임에 JITting 코드에 소비 된 계산주기는 정의상 프로그램 실행에 사용할 수 없습니다.
JITter의 모든 핫 경로는 CPU의 명령 및 데이터 캐시 코드와 경쟁합니다. 우리는 캐시가 성능면에서 지배적이며 C ++와 같은 모국어에는 정의에 따라 이러한 유형의 경합이 없습니다.
런타임 최적화 프로그램의 시간 예산은 컴파일 타임 최적화 프로그램의 예산 보다 훨씬 더 제한적입니다 (다른 의견자가 지적했듯이)
결론은 : 궁극적으로, 당신은 할 것이다 거의 확실하게 당신이 C #의 수보다 C ++로 빠른 구현을 만들 수 있습니다 .
이제 말했듯이, 작업, 문제 영역, 하드웨어, 구현 품질 및 기타 많은 요인과 같은 변수가 너무 많기 때문에 실제로 얼마나 빨리 정량화 할 수 없습니까? 시나리오에서 테스트를 실행하여 성능의 차이를 판별 한 후 추가 노력과 복잡성에 대한 가치가 있는지 여부를 결정합니다.
이것은 매우 길고 복잡한 주제이지만 C #의 런타임 최적화 프로그램이 우수하다는 완전성을 위해 언급 할 가치가 있으며 런타임에 C ++에서는 컴파일 타임으로 사용할 수없는 특정 동적 최적화를 수행 할 수 있습니다 ( static) 옵티 마이저. 그럼에도 불구하고, 장점은 여전히 기본 응용 프로그램의 법원에 깊이 있지만, 동적 최적화 프로그램은 위에서 언급 한 " 거의 확실하게"한정자 의 이유입니다 .
-
상대적인 성과 측면에서, 나는 다른 답변에서 본 인물과 토론에 혼란을 겪었습니다. 따라서 동시에 차임 할 것이라고 생각했으며 위에서 언급 한 진술에 대한 약간의 지원을 제공했습니다.
이러한 벤치 마크 문제의 큰 부분은 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);
}
런타임 (릴리스) : 초기화 : 124ms, 채우기 : 165ms
C ++ 14 (클랑 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 # 구현을 동일한 1d 배열 구현으로 변경하면 Init : 40ms, Fill : 171ms, Total : 211ms가 발생했습니다 ( C ++은 여전히 거의 40 % 빠릅니다 ).
C ++에서 "빠른"코드를 디자인하고 작성하는 것이 어느 언어로든 "일반"코드를 작성하는 것보다 훨씬 어렵습니다.
C ++에서 성능이 저하되는 것은 놀랍도록 쉽습니다. 우리는 예약되지 않은 벡터 성능으로 그것을 보았습니다. 그리고 이런 함정이 많이 있습니다.
C #의 성능은 런타임에 진행되는 모든 것을 고려할 때 다소 놀랍습니다. 그리고 그 성능은 비교적 접근하기 쉽습니다.
C ++과 C #의 성능을 비교 한 일화적인 데이터 : https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=gpp&lang2=csharpcore
결론적으로 C ++은 성능을 훨씬 더 잘 제어 할 수 있다는 것입니다. 포인터를 사용 하시겠습니까? 참조? 스택 메모리? 더미? 동적 다형성 또는 정적 다형성 (템플릿 / CRTP를 통해)으로 vtable의 런타임 오버 헤드를 제거합니까? 당신이 ... 어이 C ++에서 얻을 이상적으로 너무 솔루션 최선 주소 문제가 당신에게있는 거 태클이 (더) 자신이 모든 선택을 할 수 있도록.
위의 사소한 예에서도 성능이 크게 개선되었지만 액세스에 더 많은 투자가 필요하다는 것을 알 수 있기 때문에 실제로 해당 제어를 원하거나 필요로하는지 자문 해보십시오.
int[,]
...
내 경험 (그리고 두 언어로 많은 일을했습니다)에서 C ++과 비교 한 C #의 주요 문제는 높은 메모리 소비이며 제어 할 수있는 좋은 방법을 찾지 못했습니다. .NET 소프트웨어의 속도를 늦추는 것은 메모리 소비였습니다.
또 다른 요소는 JIT 컴파일러가 런타임에 실행되기 때문에 고급 최적화를 수행하는 데 너무 많은 시간을 할애 할 수 없으며 최종 사용자가 시간이 너무 오래 걸리면이를 알 수 있다는 것입니다. 반면에 C ++ 컴파일러는 컴파일 타임에 최적화를 수행하는 데 필요한 모든 시간을 갖습니다. 이 요소는 메모리 소비보다 훨씬 덜 중요합니다 (IMHO).
C ++이 여전히 우위에 있고 (수년 동안) 앞으로 다가올 결정이 컴파일 타임에 사전 결정될 수있을 때 발생하는 특정 시나리오입니다.
일반적으로 캡슐화 및 지연된 의사 결정은 코드를보다 역동적이고 변화하는 요구 사항에 쉽게 적용하고 프레임 워크로 사용하기 쉽기 때문에 좋습니다. 이것이 C #의 객체 지향 프로그래밍이 매우 생산적이고 "일반화"라는 용어로 일반화 될 수있는 이유입니다. 불행하게도, 이러한 특정 종류의 일반화는 런타임에 비용이 발생합니다.
일반적으로이 비용은 실질적이지 않지만 가상 메소드 호출 및 오브젝트 작성의 오버 헤드로 인해 차이가 발생할 수있는 애플리케이션이 있습니다 (특히 가상 메소드가 메소드 호출 인라이닝과 같은 다른 최적화를 방해하므로). 당신이없는 일반화 다른 종류의 달성하기 위해 템플릿을 사용할 수 있기 때문에 C ++는 큰 장점을 가지고있는 곳이다 더 런타임에 영향을하지만 반드시 덜 다형성 OOP 이상입니다. 실제로 OOP를 구성하는 모든 메커니즘은 템플릿 기술과 컴파일 타임 해상도 만 사용하여 모델링 할 수 있습니다.
이러한 경우 (그리고 종종 특수한 문제 영역으로 제한됨), C ++는 C # 및 유사한 언어에 대해 승리합니다.
sort(arr, generic_comparer)
C ++ (또는 그 문제에 대한 C)를 사용하면 데이터 구조를 세밀하게 제어 할 수 있습니다. 비트 트위스 티를 원하면 해당 옵션이 있습니다. Java / .NET 라이브러리의 내부 데이터 구조를 사용하는 대규모 관리 Java 또는 .NET 앱 (OWB, Visual Studio 2005 )은 수하물을 가지고 다닙니다. 큐브 또는 ETL 디자인을 위해 400MB가 넘는 RAM과 BIDS를 사용하는 OWB 디자이너 세션도 100MB에 도달하는 것을 보았습니다 .
예측 가능한 워크로드 (예 : 프로세스를 여러 번 반복하는 대부분의 벤치 마크와 같은)에서 JIT는 실질적인 차이가 없을 정도로 충분히 최적화 된 코드를 얻을 수 있습니다.
큰 응용 프로그램의 IMO는 코드 자체가 사용하는 데이터 구조만큼 큰 차이가 아닙니다. 응용 프로그램의 메모리가 많은 경우 캐시 사용 효율이 떨어집니다. 최신 CPU의 캐시 미스는 상당히 비쌉니다. C 또는 C ++가 실제로이기는 곳은 CPU 캐시와 잘 작동하도록 데이터 구조 사용을 최적화 할 수있는 곳입니다.
그래픽의 경우 표준 C # 그래픽 클래스는 C / C ++를 통해 액세스 한 GDI보다 느립니다. 나는 이것이 언어 자체와는 아무런 관련이 없다는 것을 알고 있습니다. 전체 .NET 플랫폼과 관련이 있지만 그래픽은 개발자에게 GDI 대체품으로 제공되는 것이며 성능이 너무 나빠 그래픽을 감히하지 않을 것입니다. 그것으로.
그래픽 라이브러리의 속도를 확인하는 데 사용하는 간단한 벤치 마크가 있으며 이는 단순히 창에 임의의 선을 그리는 것입니다. C ++ / GDI는 여전히 10000 개의 라인을 가지고 있지만 C # / Graphics는 1000 개의 실시간 작업을 수행하는 데 어려움이 있습니다.
가비지 수집은 Java #을 실시간 시스템에 사용할 수없는 주된 이유입니다.
GC는 언제 발생합니까?
얼마나 걸릴까요?
이것은 비 결정적입니다.
우리는 C #이 성능면에서 C ++과 비교할 수 있는지 확인해야했고이를 위해 몇 가지 테스트 프로그램을 작성했습니다 (두 언어 모두 Visual Studio 2005 사용). 가비지 수집이없고 언어 (프레임 워크 아님) 만 고려하면 C #은 기본적으로 C ++과 동일한 성능을 갖습니다. 메모리 할당이 C ++보다 C ++에서 훨씬 빠르며 데이터 크기가 캐시 라인 경계를 넘어서 증가 할 때 C #은 결정론에서 약간 우위에 있습니다. 그러나이 모든 비용은 결국 지불해야했으며 가비지 수집으로 인해 C #의 비 결정적 성능 적중 형태로 막대한 비용이 발생했습니다.
평소와 같이 응용 프로그램에 따라 다릅니다. C #이 무시할 수있을 정도로 느리거나 C ++이 5 배나 10 배 더 빠른 경우가 있습니다 (특히 작업을 쉽게 SIMD 할 수있는 경우).
C / C ++는 큰 배열이나 배열에 대한 반복 / 반복 (모든 크기)이있는 프로그램에서 훨씬 더 잘 수행 할 수 있습니다. 무거운 배열 연산은 거의 모든 그래픽 연산의 기본이기 때문에 C / C ++에서 그래픽이 일반적으로 훨씬 빠르기 때문입니다. .NET은 모든 안전 검사로 인해 배열 인덱싱 작업에서 느리게 알려져 있으며 특히 다차원 배열의 경우에 해당합니다 (예 : 직사각형 C # 배열이 들쭉날쭉 한 C # 배열보다 느림).
C / C ++의 보너스는 포인터를 직접 고수하고 Boost 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 ++ 원시 포인터 버전은 C #보다 약 2.1 배 빠릅니다. C # 프로그램은 안전한 코드 만 사용했습니다 unsafe
. 키워드 를 사용하기 전에 C ++로 코드를 작성할 수도 있습니다 .
누군가 내가 C #에 대해 뭔가가 있다고 생각하지 않도록 C #이 아마도 내가 가장 좋아하는 언어라고 말하면서 닫을 것이다. 내가 지금까지 본 가장 논리적이고 직관적이며 빠른 개발 언어입니다. C #에서 프로토 타이핑을 모두합니다. C # 언어는 Java에 비해 작고 미묘한 장점이 많습니다 (예, Microsoft가 게임에 늦게 들어 와서 Java를 복사함으로써 Java의 많은 단점을 해결할 수있는 기회가 있음을 알고 있습니다). 자바 Calendar
클래스 누구에게 건배 ? Microsoft가 CLR 및 .NET JITter를 최적화하기 위해 실제 노력을 기울이면 C #이 심각하게 인수 할 수 있습니다. 솔직히 그들이 아직 C # 언어로 많은 일을 해냈다는 것에 놀랐습니다. 왜 컴파일러 최적화를 사용하지 않습니까? 어쩌면 우리 모두가 애원한다면
new T[]
A가 대응 delete[]
" - 아니 당신은하지 않습니다. 거기에 std::unique_ptr
당신을 위해 그렇게 할 수 있습니다.
> 내가들은 내용에서 ...
귀하의 어려움은 귀하가들은 내용이 믿을만한 지 판단하는 데있는 것 같으며,이 사이트의 답변을 평가하려고 할 때 어려움이 반복 될 것입니다.
사람들이 여기서 말하는 것이 원래 들었던 것보다 다소 신뢰할 만한지를 어떻게 결정할 것입니까?
한 가지 방법은 증거 를 요구하는 것 입니다.
사람의 주장이 "C # 빠른 C보다 증명하는 몇 가지 영역이 있습니다 ++"때 그들에게 왜 그들이 그런 말 당신에게 측정을 보여주기 위해 그들에게 당신에게 프로그램을 표시하도록 요청합니다. 때때로 그들은 단순히 실수했을 것입니다. 때때로 당신은 그들이 사실로 보여줄 수있는 것을 공유하기보다는 단지 의견을 표현하고 있다는 것을 알게 될 것입니다.
사람들이 주장하는 내용에 정보와 의견이 혼동되는 경우가 많으며, 어느 것이 어떤 것인지 시도하고 정리해야합니다. 예를 들어,이 포럼의 답글에서 :
" 이 코드는 대부분 코드와 거의 유사하지 않기 때문에 http://shootout.alioth.debian.org/ 에서 많은 회의론을 가지고 벤치 마크를 수행 하십시오 ."
"이 큰 테스트 산술 코드"의 의미 를 실제로 이해했는지 확인한 다음 저자가 실제로 자신의 주장이 사실임을 보여 주 었는지 스스로에게 물어보십시오.
"그것은 개별 프로그램이 얼마나 잘 최적화되었는지에 달려 있기 때문에 다소 쓸모없는 테스트입니다. 나는 그 중 일부를 4-6 배 이상 가속화하여 최적화되지 않은 프로그램 간의 비교가 바보."
저자가 실제로 "그들 중 일부를 4-6 배 이상 가속시킬 수 있음"을 보여 주 었는지 스스로에게 물어보십시오. 쉽게 주장 할 수 있습니다!
C ++에서 Intel TBB 및 OpenMP를 사용할 때 '거의 병렬 처리'문제의 경우 C # 및 TPL로 수행 한 유사한 (순수한 수학) 문제와 비교하여 대략 10 배의 성능 향상이 관찰되었습니다. SIMD는 C #이 경쟁 할 수없는 영역이지만 TPL에 상당한 오버 헤드가 있다는 인상을 받았습니다.
즉, 멀티 스레드를 수행하고 결과를 빠르게 얻을 수 있다는 것을 알고 성능이 중요한 작업에만 C ++을 사용합니다. 다른 모든 것에는 C # (그리고 때로는 F #)이 좋습니다.
실제 결정적인 대답이없는 매우 모호한 질문입니다.
예를 들어; 오히려 C #보다 C ++로 만들어진 3D 게임을하고 싶습니다. 성능은 확실히 훨씬 우수하기 때문입니다. (그리고 나는 XNA 등을 알고 있지만 실제와는 거리가 멀다.)
한편, 앞서 언급 한 바와 같이; 원하는 것을 빨리하고 필요한 경우 최적화 할 수있는 언어로 개발해야합니다.
.NET 언어는 C ++ 코드만큼 빠르거나 더 빠를 수 있지만 C ++ 코드는 일시 정지 가 매우 영리하더라도 .NET 런타임이 GC 에 대해 일시 중지해야하기 때문에 처리량이 더 일정 합니다.
따라서 일시 중지하지 않고 일관되게 빠르게 실행해야하는 코드가있는 경우 .NET은 런타임 GC에 매우주의를 기울이더라도 어느 시점에서 대기 시간 을 발생 시킵니다.
이론적으로 장기 실행 서버 유형 응용 프로그램의 경우 JIT 컴파일 언어가 크게 될 수 있습니다. 기본적으로 컴파일 보다 빠를 . JIT 컴파일 언어는 일반적으로 상당히 낮은 수준의 중간 언어로 먼저 컴파일되므로 어쨌든 컴파일 시간에 많은 고급 최적화를 수행 할 수 있습니다. JIT는 응용 프로그램 사용 방법에 대한 데이터가 점점 많아지면서 코드 섹션을 즉시 다시 컴파일 할 수 있다는 장점이 있습니다. 분기 예측이 가능한 한 자주 성공하도록 가장 일반적인 코드 경로를 정렬 할 수 있습니다. 캐시에 둘 다 유지하기 위해 종종 함께 호출되는 별도의 코드 블록을 재정렬 할 수 있습니다. 내부 루프를 최적화하는 데 더 많은 노력을 기울일 수 있습니다.
나는 이것이 .NET 또는 JRE 중 하나에 의해 수행된다는 것을 의심하지만, 대학에있을 때 다시 연구되고 있었기 때문에 이러한 종류의 것들이 어느 시점에서 곧 현실 세계로 나아갈 수 있다고 생각하는 것은 합리적이지 않습니다. .
vector
C ++ 및 C #과 동등한 List
2D 배열로 테스트 했습니다 .
Visual C # / C ++ 2010 Express 버전을 사용하고 있습니다. 두 프로젝트 모두 간단한 콘솔 응용 프로그램이며 표준 (사용자 정의 설정 없음) 릴리스 및 디버그 모드에서 테스트했습니다. C # 목록은 내 PC에서 더 빠르게 실행되고 C #에서는 배열 초기화가 더 빠르며 수학 연산이 느려집니다.
Intel Core2Duo P8600@2.4GHz, C #-.NET 4.0을 사용하고 있습니다.
벡터 구현이 C # 목록과 다르다는 것을 알고 있지만 객체를 저장하고 인덱스 접근자를 사용할 수있는 컬렉션을 테스트하고 싶었습니다.
물론 메모리를 비워야합니다 (을 사용할 때마다 말하십시오 new
).하지만 코드를 단순하게 유지하고 싶었습니다.
C ++ 벡터 테스트 :
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 # 목록 테스트 :
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 ++-배열 :
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 #-배열 :
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);
}
시간 : (릴리즈 / 디버그)
C ++
(예, 13 초, 디버그 모드에서 항상 목록 / 벡터에 문제가 있습니다.)
씨#:
글쎄요. 바이트 코드가 JIT뿐만 아니라 기계 코드로 변환 된 경우 (프로그램을 실행하면 의미합니다) 와 프로그램이 많은 할당 / 할당 해제를 사용하는 경우가 더 빨리하기 때문에 될 수 GC의 알고리즘은 하나 개의 통과가 필요합니다 (이론적으로) 전체 메모리를 한 번만 통과하지만 정상적인 malloc / realloc / free C / C ++ 호출은 모든 호출에서 오버 헤드를 유발합니다 (콜 오버 헤드, 데이터 구조 오버 헤드, 캐시 누락;).
따라서 이론적으로 가능합니다 (다른 GC 언어에서도 가능).
나는 사용할 수 없다는 극단적 인 단점을 실제로 보지 못합니다. 대부분의 프로그래머가 어쨌든 그것을 사용하지 않기 때문에 대부분의 응용 프로그램에서 C #으로 메타 프로그래밍 보지 못합니다.
또 다른 큰 장점은 LINQ "확장" 과 같은 SQL 이 컴파일러가 데이터베이스 호출을 최적화 할 수있는 기회를 제공한다는 것입니다 (즉, 컴파일러는 호출 된 함수가 인라인되거나 귀하의 사용을 위해 최적화되었지만 여기에서 추측하고 있습니다).
C #으로 작성된 응용 프로그램이 빠르게 실행되고 더 많은 C ++로 작성된 응용 프로그램이 빨리 실행되고 있다고 가정합니다 (C ++은 이전 버전
이지만 UNIX도 사용합니다 ...) -실제로 질문은-그게 뭐죠, 사용자 개발자들이 불평하고 있습니다 ...
IMHO, C #의 경우 UI가 매우 편안하고 라이브러리 계층이 훌륭하며 CLI의 전체 인터페이스 시스템이 있습니다. C ++의 경우 템플릿, ATL, COM, MFC 및 OpenGL, DirectX 등과 같은 이미 작성되고 실행되는 코드의 전체 내용이 있습니다 ... 잠깐만-쾅! 멈췄다).
C #에서 코드를 매우 간단하고 빠르게 작성하려면 (오류 가능성도 증가시키는 것을 잊지 마십시오. C ++의 경우 개발자는 메모리 누수에 대해 불평합니다. 크래쉬, DLL 간 호출 및 "DLL 지옥"문제- 새로운
언어로 라이브러리를 지원하고 교체 할 수 있습니다 ... 프로그래밍 언어에 더 많은 기술이있을수록 소프트웨어의 품질과 속도가 향상 될 것입니다.
더 빠른 코드를 작성하는 프로그래머, 현재 머신의 속도를 빠르게하는 것에 대해 더 잘 알고있는 프로그래머, 우연히도 정확한 저수준 및 결정론을 가능하게하는 적절한 도구를 사용하는 프로그래머 최적화 기술. 이러한 이유로 C # 대신 C / C ++를 사용하는 사람들이이 사람들입니다. 나는 이것을 사실로 진술 할 것입니다.
내가 실수하지 않으면 C # 템플릿은 런타임에 결정됩니다. C ++의 컴파일 타임 템플릿보다 느려 야합니다.
그리고 다른 많은 사람들이 언급 한 다른 모든 컴파일 타임 최적화와 안전 부족으로 인해 더 빠른 속도를 의미 할 때 ...
C ++이 원시 속도와 최소 메모리 소비 측면에서 확실한 선택이라고 말하고 싶습니다. 그러나 이것은 또한 코드를 개발하고 메모리 누수 나 널 포인터 예외가 발생하지 않도록하는 데 더 많은 시간을 요구합니다.
평결:
C # : 더 빠른 개발, 더 느린 실행
C ++ : 느린 개발, 빠른 실행.
실제로 코드에서 수행하려는 작업에 따라 다릅니다. VB.NET, C # 및 관리되는 C ++간에 성능 차이가 있다는 것은 도시의 전설 일 뿐이라고 들었습니다. 그러나 적어도 문자열 비교에서 관리되는 C ++은 C #의 바지를 능가하고 VB.NET의 바지를 능가하는 것으로 나타났습니다.
언어 간 알고리즘 복잡성에 대한 철저한 비교를 한 적이 없습니다. 또한 각 언어의 기본 설정을 사용하고 있습니다. VB.NET에서는 변수 선언 등을 요구하는 설정을 사용하고 있습니다. 관리되는 C ++에 사용하는 코드는 다음과 같습니다. (이 코드는 매우 간단합니다). .NET 4.6.2가 설치된 Visual Studio 2013의 다른 언어에서도 동일하게 실행됩니다.
#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 ++ 사이에는 몇 가지 주요 차이점이 있습니다.
그 외에도 프로그래머 역량도 중요한 역할을합니다. 나는 값으로 전달 된 클래스가 인수로 전달되는 나쁜 C ++ 코드를 보았습니다. 수행중인 작업을 모르는 경우 실제로 C ++에서 성능을 악화시킬 수 있습니다.
> 결국 답은 어딘가에 있어야합니까? :)
음.
여러 답변에서 언급했듯이 질문이 답변이 아닌 답변으로 초대하는 방식으로 질문이 잘못 지정 되었습니다. 한 가지 방법 만 사용하려면 :
그리고 어떤 프로그램? 어떤 기계? 어떤 OS? 어떤 데이터 세트?
이로부터 영감을 얻어, 나는 대부분의 프로그램에 필요한 일반적인 지시의 60 %로 빠른 테스트를했습니다.
C # 코드는 다음과 같습니다.
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();
}
문자열 배열과 arraylist는 이러한 명령어를 포함하기 위해 의도적으로 사용됩니다.
C ++ 코드는 다음과 같습니다.
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();
}
내가 사용한 입력 파일 크기는 40KB입니다.
결과는 다음과 같습니다.
아, 그러나 이것은 Linux에서 ... C #이 Mono에서 실행되고 C ++는 g ++로 실행되었습니다 .
좋아, 이것이 Windows에서 얻은 것 – Visual Studio 2003 :