왜 C가 그렇게 빠르며 다른 언어가 그렇게 빠르거나 빠르지 않습니까? [닫은]


208

StackOverflow 팟 캐스트를 들으면서 b은 "실제 프로그래머"가 C로 작성하고 C가 "머신에 가깝기 때문에"훨씬 빠릅니다. 다른 게시물에 대한 이전 주장을 남겨두고 다른 언어보다 더 빠를 수있는 C의 특별한 점은 무엇입니까? 또는 다른 방법으로 말하면 다른 언어가 C만큼 빨리 실행되는 바이너리로 컴파일 할 수 없도록하는 것은 무엇입니까?


6
어떤 특정 쇼가 이것에 대해 이야기했는지 열거 할 수 있습니까? 나는 그것을 듣고 싶습니다.
Giovanni Galbo

2
이 질문에 얼마나 잘못 대답했는지 (대부분의 답변은 컴파일 된 언어와 해석 된 언어의 근본적인 차이점을 무시하고 JIT yada yada yada에 대해 알고 있습니다) 얼마나 많은 사람들이 자신의 좋아하는 언어를 방어하는 입장을 취하고 있는지에 대해 놀랐습니다 (FORTRAN 소년 필요) 알약을 복용).
Tim Ring

어셈블리 언어를 잊지 마십시오. 어셈블리 조립 exe보다 빠르거나 컴팩트 한 것은 없습니다. 어셈블리는 거의 순수한 바이너리이므로 가장 빠른 언어 편견이 없습니다.
KKZiomek 2016 년

3
빛의 속도와 상대성 때문에 C가 가장 빠릅니다.
Taraviya 만나기

물론 C가 가장 빠른 프로그램 언어 인 것은 잘못된 일입니다. FORTH의 속도에 가까운 프로그램 언어는 없습니다. FORTH는 핵폭탄을 발사하는 데 사용되며, 대부분의 위성에서 사용되는 프로그램 언어이며 국제 우주 정거장의 주요 프로그램 언어이며 CERN 및 ITER에서도 사용됩니다. Microsoft C (다른 버전)와 FORTH 간의 속도를 비교하고있었습니다. YAWN에서 C로 ...
Scoobeedo Cool 1

답변:


200

C에 대해서는 특별한 점이 많지 않습니다. 이것이 빠른 이유 중 하나입니다.

가비지 수집 , 동적 입력 및 기타 기능을 지원하는 최신 언어로 프로그래머가 프로그램을보다 쉽게 ​​작성할 수 있습니다.

캐치에는 응용 프로그램의 성능을 저하시키는 추가 처리 오버 헤드가 있습니다. C에는 그 중 하나가 없으므로 오버 헤드가 없다는 것을 의미하지만 프로그래머는 메모리 누수 를 방지하기 위해 메모리 를 할당하고 해제 할 수 있어야합니다. 해야하며 변수의 정적 입력을 처리해야합니다.

즉, Java ( Java Virtual Machine 사용 ) 및 .NET (Common Language Runtime 사용)과 같은 많은 언어와 플랫폼 은 기본 기계 코드를 생성하는 JIT (Just-In-Time) 컴파일 과 같은 출현으로 수년 동안 성능이 향상되었습니다. 더 높은 성능을 달성하기 위해 바이트 코드.


3
가비지 콜렉션은 수동 메모리 관리 (단기 프로그램 및 / 또는 많은 메모리의 경우)보다 빠를 수 있습니다. GC는 간단하고 빠른 할당을 허용하며 프로그램은 할당을 해제하는 데 시간을 소비하지 않습니다.
Kornel

2
C 프로그램은 일반적으로 필요에 따라 메모리를 할당 및 할당 해제합니다. 이것은 비효율적입니다. 좋은 VM은 큰 청크로 할당 및 할당 해제하여 많은 경우 성능을 크게 향상시킵니다.
skaffman 2016 년

60
C 프로그램이 "하드"를 제외하고 동일한 청크 할당 및 가비지 수집을 수행하는 것을 막을 수있는 것은 없습니다.
ephemient 2016 년

아주 잘 말하지만 Rob Allen은 C가 Java 또는 .NET보다 추상화를 덜 제공하므로 번역 횟수가 줄어 들었습니다 (귀하와 같이 JIT (Just-In-Time) 컴파일로 인해 오늘날에는 덜 사실입니다)
Gab Royer

5
porneL, 수동 관리 및 현명한 할당은 올바르게 사용될 때 항상 모든 GC 시스템보다 성능이 뛰어나고 많은주의를 기울이고, 사용 패턴에 대한 절대적인 지식을 가지고 있으며, GC는 그렇지 않으며 GC 시스템은 오버 헤드를 추가합니다
Ion Todirel

89

C 디자이너가 만든 거래가 있습니다. 즉, 그들은 안전보다 속도를 높이기로 결정했습니다. C는하지 않습니다

  • 배열 인덱스 범위 확인
  • 초기화되지 않은 변수 값 확인
  • 메모리 누수 확인
  • 널 포인터 역 참조 확인

Java로 배열에 색인을 생성하면 가상 시스템에서 일부 메소드 호출, 바운드 검사 및 기타 온 전성 검사가 필요합니다. 그것은 유효하고 절대적 으로 좋습니다. 왜냐하면 그것이 예정된 곳에 안전을 추가하기 때문입니다. 그러나 C에서는 아주 사소한 것조차 안전하지 않습니다. 예를 들어 C에서는 복사 할 영역이 겹치는 지 확인하기 위해 memcpy가 필요하지 않습니다. 그건 하지 큰 비즈니스 응용 프로그램을 프로그래밍하는 언어로 설계.

그러나 이러한 디자인 결정은 C 언어의 버그아닙니다 . 컴파일러와 라이브러리 작성자가 컴퓨터에서 모든 성능을 얻을 수 있도록 설계되어 있습니다. 다음은 C 이론 문서에서 설명 하는 C 의 정신입니다 .

C 코드는 이식 할 수 없습니다. 프로그래머가 실제로 이식 가능한 프로그램을 작성할 수있는 기회를 제공하기 위해 노력했지만위원회는 프로그래머를 이식 가능하게 작성하여 C를``고수준 어셈블러 ''로 사용하는 것을 배제하기를 원하지 않았습니다. 코드는 C의 장점 중 하나입니다.

C의 정신을 유지하십시오. 위원회 는 C 의 전통적인 정신을 보존하기위한 주요 목표로 유지했습니다. C의 정신에는 여러 가지 측면이 있지만, 본질은 C 언어의 기반이되는 기본 원칙에 대한 공동체의 정서입니다. C의 정신의 일부 측면은 다음과 같은 문구로 요약 될 수 있습니다.

  • 프로그래머를 신뢰하십시오.
  • 프로그래머가 수행해야 할 작업을 방해하지 마십시오.
  • 언어를 작고 단순하게 유지하십시오.
  • 작업을 수행하는 한 가지 방법 만 제공하십시오.
  • 휴대 성이 보장되지 않더라도 빨리 만드십시오.

마지막 잠언에는 약간의 설명이 필요합니다. 효율적인 코드 생성 가능성은 C의 가장 중요한 강점 중 하나입니다. 매우 간단한 작업으로 보이는 코드 폭발이 발생하지 않도록하기 위해 많은 작업이 대상 시스템의 하드웨어가 아닌 일반적인 추상 규칙. 기계가하는 것과 함께 살려는 이러한 의지의 예는 표현식에 사용하기 위해 char 객체의 확장을 결정하는 규칙에서 볼 수 있습니다. 대상 머신에서 효율적입니다.


51
C는 심하게 충돌하여 널 포인터 무시를 검사합니다. :-). 또한 때때로 스택 프레임과 데이터를 망쳐 범위를 벗어난 배열 인덱스와 초기화되지 않은 변수를 확인합니다. 불행히도 런타임에이를 확인합니다.
paxdiablo 2018 년

18
나는 C가 안전하지 않다고 말하지 않을 것입니다. 이것은 당신이 암시하는 것과 같습니다. 그것은 당신이 바보가 아니라고 가정합니다. 총을 겨누고 발로 쏘면 C는 기꺼이 자신을 현명하다고 가정하기 때문에 기꺼이 그 일을하게 할 것입니다. 반드시 나쁜 것은 아닙니다.
Bob Somers

19
@ 밥 : 정확합니다. C를 말하는 것은 위험한 일을 할 수 있기 때문에 안전하지 않다는 말은 자동차가 안전하지 않다고 말하는 것과 같습니다. C는 운전을하는 사람만큼 안전하지만 안전하지 않은 운전자가 많이 있습니다.
Robert Gamble

5
밥, 버퍼 오버런과 같은 버그를 만든다고해서 바보가되는 것은 아닙니다. 그것은 단지 당신이 여전히 인간임을 의미합니다. 나는 C와 C ++가 나쁘지 않다는 것을 알고있다 .
Johannes Schaub-litb

4
@ JohannesSchaub-litb C는 대규모 애플리케이션 프로그래밍에 적합합니다. 만약 여러분이 프로젝트를 헬로 월드보다 더 크게 만들기가 어렵다면, 문제는 언어가 아닌 프로그래머에게 있습니다.

75

한 달 동안 0.05 초 안에 실행되는 무언가를 빌드하고 Java로 같은 것을 쓰는 데 하루를 보내고 0.10 초 안에 실행하면 C가 더 빠릅니까?

그러나 귀하의 질문에 대답하기 위해, 잘 작성된 C 코드는 일반적으로 다른 언어로 작성된 잘 작성된 코드보다 빠르게 실행됩니다. C 코드 "잘 작성"의 일부에는 기계 근처에서 수동 최적화를 수행하는 것이 포함되기 때문입니다.

컴파일러는 실제로 매우 영리하지만, 여전히 손에 의한 알고리즘과 경쟁하는 코드를 창의적으로 만들 수는 없습니다 ( "손"이 우수한 C 프로그래머에 속한다고 가정 ).

편집하다:

많은 의견이 "C로 작성하고 최적화에 대해서는 생각하지 않습니다"라는 문구를 따릅니다.

그러나이 게시물에서 구체적인 예 들어보십시오 .

델파이에서는 이것을 쓸 수 있습니다 :

function RemoveAllAFromB(a, b: string): string;
var
  before, after :string;
begin
  Result := b;
  if 0 < Pos(a,b) then begin
    before := Copy(b,1,Pos(a,b)-Length(a));
    after := Copy(b,Pos(a,b)+Length(a),Length(b));
    Result := before + after;
    Result := RemoveAllAFromB(a,Result);  //recursive
  end;
end;

그리고 CI에서 이것을 작성하십시오 :

char *s1, *s2, *result; /* original strings and the result string */
int len1, len2; /* lengths of the strings */
for (i = 0; i < len1; i++) {
   for (j = 0; j < len2; j++) {
     if (s1[i] == s2[j]) {
       break;
     }
   }
   if (j == len2) {  /* s1[i] is not found in s2 */
     *result = s1[i]; 
     result++; /* assuming your result array is long enough */
   }
}

그러나 C 버전에는 얼마나 많은 최적화가 있습니까? 우리는 델파이 버전에서 생각하지 않는 구현에 대해 많은 결정을합니다. 문자열은 어떻게 구현됩니까? 델파이에서는 보이지 않습니다. C에서는 ASCII 정수 배열에 대한 포인터가 될 것이라고 결정했습니다.이를 정수라고합니다. C에서는 한 번에 하나씩 문자 존재를 테스트합니다. 델파이에서는 Pos를 사용합니다.

그리고 이것은 단지 작은 예입니다. 큰 프로그램에서 C 프로그래머는 몇 줄의 코드로 이러한 종류의 낮은 수준의 결정을 내려야합니다. 수작업으로 제작 된 수작업으로 최적화 된 실행 파일을 추가합니다.


45
그러나 공평하게 말하면 C에서는 한 달이 걸리고 Java에서는 하루가 걸리고 실행하는 데 0.05 초 밖에 걸리지 않습니다 (예 : 작은 프로그램).
dreamlax

12
나는 몇 년 동안 C로 프로그래밍했으며 거의 ​​모든 종류의 최적화를 할 필요가 없습니다. 많은 프로그램을 C (주로 Perl에서)로 이식했으며 일반적으로 수작업으로 최적화하지 않고 속도가 10 배 이상 빨라지고 메모리 사용량이 크게 줄어 듭니다.
Robert Gamble

1
물론 기존 시설이 없기 때문에 C에서 프로그래밍하는 데 상당히 오래 걸릴 수있는 것들이 있으므로 컴퓨터 성능과 프로그래머 성능 (다른 것들 중에서도) 사이의 상충 관계이므로 C에서 모든 것을 프로그래밍하지는 않습니다.
Robert Gamble

4
Java 또는 .NET 프로그램을 시작할 수있는 시간보다 짧은 시간에 수천 줄의 데이터를 처리하는 C ++ 프로그램을 만들었습니다. 그것은 더 현대적인 언어에 대한 좌절 중 하나입니다. C는 최소한의 런타임 요구 사항이 필요한 린 프로그램에 적합합니다. PowerBasic도 좋습니다.
bruceatk

35
당신은 C에서 한 달이 걸리고 Java로 작성된 프로그램보다 작성하는 데 하루 만 걸리는 것보다 두 배 빠른 프로그램은 가치가 없다고 말하고 있습니까? 해당 프로그램을 하루에 500,000,000 회 이상 실행해야하는 경우 어떻게합니까? 두 배 빠른 속도는 엄청나게 중요합니다. 수천 또는 수백만 개의 CPU에서 실행되는 경우 성능을 두 배로 향상시키기 위해 추가로 한 달간 추가 비용을 절약 할 수 있습니다. 기본적으로 개발 플랫폼을 선택하기 전에 배포 규모를 알고 이해해야합니다.
nicerobot 2016 년

49

나는 그것을 보지 못 했으므로 말할 것입니다 : C는 거의 모든 것이 C로 작성되기 때문에 더 빠릅니다 .

Java는 C로, Python은 C (또는 Java 또는 .NET 등), Perl 등으로 작성됩니다. OS는 C로 작성되고 가상 머신은 C로 작성되고 컴파일러는 C로 작성됩니다. 인터프리터는 C로 작성됩니다. 일부는 여전히 어셈블리 언어로 작성되며, 속도가 훨씬 빠릅니다. 점점 더 많은 것들이 다른 것으로 작성되고 있으며, 그 자체가 C로 작성되었습니다.

어셈블리가 아닌 다른 언어로 작성하는 각 명령문은 일반적으로 C의 여러 명령문으로 구현되며 기본 머신 코드로 컴파일됩니다. C보다 더 높은 수준의 추상화를 얻기 위해 다른 언어가 존재하는 경향이 있기 때문에 C에 필요한 추가 설명은 안전성 추가, 복잡성 추가 및 오류 처리에 중점을 두는 경향이 있습니다. 그것들은 종종 좋은 것이지만, 비용이 있으며, 그 이름은 속도크기 입니다.

개인적으로, 나는 가용 한 스펙트럼의 대부분에 걸쳐 문자 그대로 수십 개의 언어로 작성했으며, 개인적으로 당신이 암시하는 마술을 찾았습니다.

케이크도 먹고 먹을 수 있습니까? 내가 좋아하는 언어로 높은 수준의 추상화를 사용하여 연주하고 어떻게 C의 핵심에 빠뜨릴 수 있습니까?

몇 년의 연구 끝에 제 대답은 Python (C)입니다. 당신은 그것을보고 싶을 수도 있습니다. 그건 그렇고, 파이썬에서 어셈블리로 드롭 다운 할 수도 있습니다 (특별 라이브러리의 약간의 도움으로).

반면에 잘못된 코드는 모든 언어로 작성할 수 있습니다 . 따라서 C (또는 어셈블리) 코드는 자동으로 더 빠르지 않습니다 . 마찬가지로 일부 최적화 트릭은 고급 언어 코드의 일부 를 원시 C의 성능 수준에 가깝게 만들 수 있습니다. 그러나 대부분의 응용 프로그램에서 프로그램은 대부분의 시간을 사람이나 하드웨어를 기다리는 데 소비하므로 차이는 중요하지 않습니다.

즐겨.


10
이것은 실제로 JIT 컴파일 언어에는 적용되지 않습니다. 내 C #이 기계 코드로 컴파일 된 C로 변환되는 IL로 컴파일되는 것과 다릅니다. 아니요, IL은 JIT로 컴파일되며 JIT의 구현 언어는이 시점에서 관련이 없습니다. 그냥 기계 코드를 생산하고 있습니다.
Jon Skeet

3
신은 내가 전설적인 Jon Skeet에 의문을 제기하는 것을 금지했지만, 생산되는 머신 코드는 C 대신 C #을위한 것이므로 "높은 수준"이고 더 많은 기능을 가지며 안전 점검 등을 할 것입니다. 그러므로 "동등한"C보다 느리다.
Rob Williams

3
@ 존 : 비슷한 말을하려고했지만 실제로 많은 .NET 라이브러리 핵심 구성 요소가 실제로 C로 작성되어 C의 속도 제한이 있기 때문에 요점은 실제로 다소 유효합니다. 미래에 이것이 어떻게 변할지를 보는 것은 흥미로울 것입니다.
Konrad Rudolph

1
이것은 다른 언어 컴파일러 / 인터프리터 / vms가 자주 있지만 항상 c로 작성되지는 않지만 c가 매우 빠르기 때문에 (많은 경우 가장 빠름) 항상 잘못된 것은 아닙니다.
Roman A. Taycher

2
이 답변은 사실이 아닙니다. 위에서 지적했듯이 JIT 언어에는 적용되지 않지만 자체 컴파일러가있는 언어에도 적용되지 않습니다 (특별한 노력을 기울이면 현대 C 컴파일러보다 빠른 코드를 생성 할 수 있음). 왼쪽 언어의 유일한 다른 클래스는 언어를 해석하고, 사람들은하지 느린 C보다 단지 그들은 C 스스로 작성하고 있기 때문에,하지만, 아무리 해석의 오버 헤드 때문에 당신이 그것을 슬라이스하는 방법과 인터프리터는 어셈블리에 기록 된 경우에도 , 크다.
Score_Under

38

거기에는 많은 질문이 있습니다. 대부분 대답 할 자격이없는 질문입니다. 그러나이 마지막 것에는 :

다른 언어가 C만큼 빨리 실행되는 바이너리로 컴파일 할 수 없도록하는 것은 무엇입니까?

한마디로 추상화.

C는 기계어에서 한 단계 또는 두 단계의 추상화입니다. Java 및 .Net 언어는 어셈블러에서 최소 3 단계 추상화 수준에 있습니다. 파이썬과 루비에 대해 잘 모르겠습니다.

일반적으로 프로그래머 장난감 (복잡한 데이터 유형 등)이 많을수록 기계 언어에서 멀어지고 더 많은 번역을 수행해야합니다.

나는 여기 저기 있지만 기본 요점입니다.

업데이트 -------이 게시물에 대한 자세한 설명이 있습니다.


3
기술적으로 Java 및 .Net은 실행되는 기계의 기계 언어에서 무한히 추상화됩니다. 그들은 VM에서 실행됩니다. JIT를 사용하더라도 원래 기계 코드와 비슷한 것을 얻으려면 원래 코드를 엄청나게 마사지해야합니다.
jmucchiello

1
.net 코드는 VM에서 실행되지 않습니다. 실행중인 프로세서 플랫폼 (32 비트 x86, 64 비트 x86 또는 IA64)에 대한 기본 지침으로 실행됩니다.
Robert C. Barth

11
@Robert : .net VM을 사용합니다. .net 코드는 VM에 의해 실행되는 바이트 코드로 컴파일됩니다. VM은 런타임에 바이트 코드를 기본 명령어로 변환합니다.
Robert Gamble

3
그것은이다 매우 자바와 다른 객체 지향 언어 추상화 프로세서 명령어 세트에 영향을 것이 중요합니다. 최신 프로세서에는 Java VM이 이러한 최적화에 대해 알고이를 사용하는 경우 Java 실행 속도를 높이는 지침이 있습니다. 그것은 크지 않지만 도움이됩니다.
Adam Davis


35

C의 비용 모델이 투명 하기 때문에 C가 빠르지는 않습니다 . C 프로그램이 느리면 많은 문을 실행함으로써 명백한 방식으로 느려집니다. C의 작업 비용과 비교하여 객체 (특히 리플렉션) 또는 문자열에 대한 높은 수준의 작업은 명확하지 않은 비용을 가질 수 있습니다.

일반적으로 C만큼 빠른 바이너리로 컴파일되는 두 가지 언어는 표준 ML ( MLton 컴파일러 사용) 및 Objective Caml 입니다. 벤치 마크 게임 을 확인하면 바이너리 트리와 같은 일부 벤치 마크의 경우 OCaml 버전이 C보다 빠릅니다 (MLton 항목을 찾지 못했습니다). 그러나 총격을 너무 심각하게 생각하지 마십시오. 그것은 게임이 말했듯이 결과는 종종 사람들이 코드를 조정하는 데 얼마나 많은 노력을 기울 였는지 반영합니다.


모든 언어로 명백하게 비싼 코드를 작성할 수 있습니다. 일부 언어에서는 Lisp 또는 Forth의 내부 변형을 먼저 작성해야합니다.
Donal Fellows

또한 Rust는 벤치 마크에서 C와 일치합니다.
스탁

18

C가 항상 빠르지는 않습니다.

C는 예를 들어 Modern Fortran보다 느립니다.

C는 종종 Java보다 느립니다. (특히 JIT 컴파일러가 코드를 살펴본 후)

C를 사용하면 포인터 앨리어싱이 가능해 지므로 일부 최적화가 불가능합니다. 특히 여러 실행 단위가있는 경우 데이터 가져 오기가 중단됩니다. 아야

포인터 산술이 작동한다고 가정하면 실제로 일부 CPU 제품군에서 부풀린 성능이 느려집니다 (특히 PIC!) 세그먼트 x86에서 큰 것을 빨아 들였습니다.

기본적으로 벡터 장치 또는 병렬화 컴파일러를 사용하면 C 악취와 최신 Fortran이 더 빨리 실행됩니다.

썽킹 (즉시 실행 파일 수정)과 같은 C 프로그래머 트릭으로 인해 CPU 프리 페치가 중단됩니다.

당신은 드리프트를 얻을?

그리고 우리의 좋은 친구 x86은 요즘 실제 CPU 아키텍처와 거의 관계가없는 명령어 세트를 실행합니다. 섀도우 레지스터,로드 저장소 최적화 프로그램은 모두 CPU에 있습니다. 따라서 C는 가상 금속에 가깝습니다. 진짜 금속, 인텔은 당신을 보지 못하게합니다. (역사적으로 VLIW CPU는 약간의 버스트이므로 아마도 그렇게 나쁘지 않을 것입니다.)

고성능 DSP (아마도 TI DSP?)에서 C로 프로그래밍하는 경우 컴파일러는 여러 병렬 실행 장치에서 C를 풀기 위해 까다로운 작업을 수행해야합니다. 이 경우 C는 금속에 가깝지 않지만 컴파일러에 가깝기 때문에 전체 프로그램 최적화가 수행됩니다. 기묘한.

마지막으로 일부 CPU (www.ajile.com)는 하드웨어에서 Java 바이트 코드를 실행합니다. C는 PITA가 해당 CPU에서 사용할 것입니다.


1
C에서 썽킹이 마지막으로 작성된 시간은 언제입니까? 최신 x86은 대부분 RISC 디자인에 대한 인터페이스이지만 VLIW와는 거의 관련이 없습니다.
Calyth

7
귀하의 게시물 대부분은 C99의 존재를 무시합니다. 또한 많은 C / C ++ 컴파일러는 C99 제한 키워드 (포인터 앨리어싱을 보장하지 않음)를 확장으로 제공합니다.
Evan Teran

나는 모든 사람들이 CWE / SANS Top 25를 따르고 / 전환하고 C에서 새로운 디자인을하는 것을 피한다고 가정합니다. 따라서 C 필드가없고 C99도 거의 없습니다.
Tim Williscroft

2
c가 현대 Fortenberry보다 느린 경우의 예를 보여 주시겠습니까?
Adam

C 컴파일러가 최고의 Fortran 컴파일러와 경쟁하는 시간이 있는지 확실하지 않습니다. 물론 FORTRAN 77 (66 만 사용)으로 작성하고 싶지 않은 코드가 많이 있지만, 최근의 Fortran 표준은 점점 더 즐거워졌습니다.
tfb

11

다른 언어가 C만큼 빨리 실행되는 바이너리로 컴파일 할 수 없도록하는 것은 무엇입니까?

아무것도. Java 또는 .NET 언어와 같은 최신 언어는 성능보다는 프로그래머 생산성에 더 중점을 둡니다. 하드웨어는 요즘 저렴합니다. 또한 중간 표현으로 컴파일하면 보안, 이식성 등과 같은 많은 보너스가 제공됩니다. .NET CLR은 다른 하드웨어를 활용할 수 있습니다. 예를 들어 SSE 명령어 세트를 사용하기 위해 프로그램을 수동으로 최적화 / 재 컴파일 할 필요가 없습니다.


나는 여기서 이식성을 주장 할 것이다. 실제로 이식 가능한 코드를 원한다면 다른 언어가 아닌 C로 작성하십시오. 약 25 개의 운영 체제에서 실행되는 코드가 있습니다. dos와 threadX에서 시작하여 Linux / XP에서 마무리하면 다른 언어를 보여줄 수 있습니다. :)
Ilya

1
@Ilya 동의하지 않습니다. C로 이식 할 수없는 코드를 작성하는 것만 큼 쉽습니다. 64 비트로 포팅하는 것이 얼마나 고통 스러웠는지 살펴보십시오. 바이트 코드 언어는 올바른 바이트 코드 인터프리터가 있으면 플랫폼에서 작동 할 수 있습니다.
Calyth

1
@IIya, 휴대용 C 코드는 규칙이 아닌 실행입니다. 나는 다른 하드웨어 / 소프트웨어 플랫폼간에 C 코드를 포팅하고 악몽이라는 것을 알고 있습니다.
aku

PC 단어에서도 마찬가지입니다. 자바에서는 약간의 C / C ++로 작성된 크로스 플랫폼 애플리케이션의 대부분을 실제로 살펴보십시오. 임베디드 저수준 개발의 경우 다른 사례는 없습니다. C는 사실상 가장 휴대 가능한 언어입니다.
Ilya

@aku-> PORTING 잘못된 코드가 재앙 일 수 있습니다. ADVANCE-C로 휴대용 코드 작성이 최선의 선택입니다. C ++은 옵션이지만 임베디드 플랫폼으로 이동하면 항상 괜찮은 C 컴파일러를 찾을 수 있습니다 .c ++의 경우 컴파일러없이 스스로 찾을 수 있습니다.
Ilya

8

주요 요소는 정적으로 형식화 된 언어이며 기계 코드로 컴파일된다는 것입니다. 또한 저수준 언어이기 때문에 일반적으로 말하지 않은 것은 없습니다.

이것들은 생각 나는 다른 요소들입니다.

  • 변수는 자동으로 초기화되지 않습니다
  • 배열에 대한 경계 검사가 없습니다.
  • 검사되지 않은 포인터 조작
  • 정수 오버 플로우 검사 없음
  • 정적 타입 변수
  • 함수 호출은 정적입니다 (함수 포인터를 사용하지 않는 한)
  • 컴파일러 작성자는 최적화 코드를 개선하는 데 많은 시간을 보냈습니다. 또한 사람들은 최상의 성능을 얻기 위해 C로 프로그래밍하므로 코드를 최적화해야합니다.
  • 언어 사양의 일부는 구현 정의되어 있으므로 컴파일러는 가장 최적의 방식으로 작업을 자유롭게 수행

대부분의 정적 유형 언어는 C보다 빠르거나 빠르게 컴파일 할 수 있습니다. 특히 포인터 별칭으로 인해 C가 할 수 없다고 가정 할 수있는 경우 특히 그렇습니다.


C 저수준? 나는 자바와 비교할 때 상대적으로 의미가 있다고 생각하지만 어셈블리 번호와 비교합니다. 좋은 포스트, 내가 생각하게했다.
Mark

당신이 맞아요, 그것은 확실히 상대적입니다. 내 말은 그것이 "기계에 가깝다"는 것이며 메모리 관리 나 배열 크기 추적과 같은 일을하는 데 도움이되지 않는다는 것입니다.
Matthew Crumley

2
C는 저급 언어입니다. C는 항상 저수준 언어였습니다. 많은 어려움없이 C 코드를 어셈블러로 직접 번역 할 수 있습니다.
Robert C. Barth

2
@Robert : C는 어셈블리 (매우 일반적 임)와 비교할 때 고급 언어로 간주되었습니다. 오늘날 사용되는 대부분의 언어와 비교하여 저수준 언어로 간주됩니다.
Robert Gamble

솔직히 이것은 매우 편향된 답변입니다. 모든 C 프로그래머 근처에서 바운드 검사 등을 수행합니다. 그러나 C는 여전히 C ++보다 훨씬 빠릅니다.
MarcusJ

8

어셈블리 언어도 언어라는 것을 잊어 버린 것 같습니다 :)

그러나 진지하게, C 프로그램은 프로그래머가 자신이하는 일을 알고있을 때만 더 빠릅니다. 동일한 작업을 수행하는 다른 언어로 작성된 프로그램보다 느리게 실행되는 C 프로그램을 쉽게 작성할 수 있습니다.

C가 더 빠른 이유는 C가 이런 식으로 설계 되었기 때문입니다. 컴파일러가 코드를 최적화하는 데 도움이되는 많은 "낮은 수준"작업을 수행 할 수 있습니다. 또는 프로그래머가 코드를 최적화 할 책임이 있습니다. 그러나 종종 까다 롭고 오류가 발생하기 쉽습니다.

이미 언급 한 다른 언어와 같이 다른 언어는 프로그래머의 생산성에 더 중점을 둡니다. 프로그래머 시간은 기계 시간보다 훨씬 비싸다고 믿어집니다 (구시대에도). 따라서 프로그래머가 프로그램 실행 시간 대신 프로그램을 작성하고 디버깅하는 데 소요되는 시간을 최소화하는 것이 좋습니다. 그렇게하려면 많은 것들이 자동화되기 때문에 프로그램을 더 빨리 만들기 위해 할 수있는 일을 조금 희생해야합니다.


3
C에서 한 번, 어셈블리에서 다시 한 번 프로그램을 작성했지만 컴파일러가 더 똑똑하기 때문에 C 버전이 더 빠를 것입니다.
mk12

7

대부분의 경우 모든 C 명령어는 매우 적은 어셈블러 명령어에 해당합니다. 기본적으로 더 높은 수준의 기계 코드를 작성하므로 프로세서가 수행하는 거의 모든 것을 제어 할 수 있습니다. C ++과 같은 다른 많은 컴파일 된 언어에는 생각보다 훨씬 더 많은 코드로 변환 할 수있는 많은 간단한 명령어가 있습니다 (가상 함수, 복사 생성자 등). Java 또는 Ruby와 같은 해석되는 언어에는 다른 계층이 있습니다. 가상 머신 또는 인터프리터


그리고이 고급 언어 중 일부는 처음에 추가 한 크래프트를 대부분 제거 할 수 있다는 점에서 자부심을 느낍니다. C ++에서 복사 제거, 반환 값 최적화, 이동 구성 / 할당 등과 같은 것들.
cmaster-모니카 복원

코드에서 생성 된 어셈블리 명령어의 수에 따라 결정됩니다. 높은 수준의 코드 줄당 더 많은 어셈블리 명령이있을수록 성능이 더 많이 저하됩니까?
ENDEESA

지나치게 단순화 된 것일 수도 있지만 조립 명령 수와 프로그램 속도 사이에는 직접적인 관계가 있습니다. 프로세서가 각 명령을 실행하는 데 필요한 최소 시간이 있습니다. 작성중인 명령 수를 쉽게 이해할 수있는 언어 인 IMHO는보다 효율적인 코드 작성에 도움이됩니다. (분기 및 캐시 미스와 같은 다른 프로세서 시간 비용이 있지만, 추상화가 적더라도 CPU가 수행하는 작업을 명확하게하는 데 도움이됩니다).
AShelly


7

C ++은 평균적으로 더 빠릅니다 (처음에는 약간의 차이가 있지만 C의 상위 집합이므로). 그러나 특정 벤치 마크의 경우 종종 더 빠른 다른 언어가 있습니다.

https://benchmarksgame-team.pages.debian.net/benchmarksgame/

fannjuch-redux 스칼라에서 가장 빠른

n-body그리고 fasta빠른 에이다에 있었다.

spectral-norm 포트란에서 가장 빠릅니다.

reverse-complement, mandelbrotpidigitsATS에서 가장 빠른했다.

regex-dna JavaScript에서 가장 빠릅니다.

chameneou-redux 가장 빠른 것은 Java 7입니다.

thread-ring Haskell에서 가장 빠릅니다.

나머지 벤치 마크는 C 또는 C ++에서 가장 빠릅니다.


"C의 슈퍼 세트이므로"-아니오, C ++는 C의 슈퍼 세트가 아닙니다 .
PP

1
extern "C"C ++가 C의 상위 집합 이 되는 것과는 아무 관련이 없습니다 .
PP

2
마치 system("bash script.sh");모든 bash 스크립트에서 작동하는 것과 같으므로 C는 bash의 상위 집합입니다. extern "C"이름 맹 글링으로 인해 C ++에서 C 연결을 제공합니다. X를 Y의 수퍼 셋으로 호출하는 것은 Y에서 수행 할 수있는 모든 작업을 X에서도 수행 할 수 있음을 의미하지만 C ++에서는 그렇지 않습니다. C에서는 유효하지만 C ++에서는 유효하지 않은 언어 구성이 꽤 있습니다.
PP

1
@PP C ++ 표준 bash에는 사용 가능한 명령 줄 프로그램 인 명령이 없습니다. 지원해야 할 bash의 버전 / 사양을 포함하고 포함했다면 상위 집합으로 간주됩니다.
피터로 레이

1
C ++ 코드가 아닌 C 코드를 작성하는 것은 간단합니다.struct foo { int: this; }; typedef float foo;
Jasen

6

이러한 답변 중 많은 부분이 C가 더 빠르거나 그렇지 않은 이유에 대한 정당한 이유를 제시합니다 (일반적으로 또는 특정 시나리오에서). 다음과 같은 사실은 부인할 수 없습니다.

  • 다른 많은 언어들은 우리가 당연한 것으로 생각하는 자동 기능을 제공합니다. 예를 들어, 경계 검사, 런타임 유형 검사 및 자동 메모리 관리는 무료로 제공되지 않습니다. 이러한 기능과 관련된 비용 은 적어도 일부 있으며, 이러한 기능을 사용하는 코드를 작성하는 동안 생각하지 않거나 심지어 실현하지 못할 수도 있습니다.
  • 소스에서 머신으로의 단계는 종종 C 에서처럼 다른 언어로 직접적이지 않습니다.
  • OTOH는 컴파일 된 C 코드가 다른 언어로 작성된 다른 코드보다 빠르게 실행된다고 말하는 것은 항상 사실이 아닌 일반화입니다. 반대의 예는 쉽게 찾을 수 있습니다.

그럼에도 불구하고, 나는 다른 요소보다 C와 다른 많은 언어의 비교 성능에 더 크게 영향을 미친다는 것을 알았습니다. 재치 :

다른 언어는 종종 더 느리게 실행되는 코드를 작성하기가 더 쉽습니다. 종종 언어의 디자인 철학에 의해 장려되기도합니다. Corollary : C 프로그래머는 불필요한 작업을 수행하지 않는 코드를 작성할 가능성이 높습니다.

예를 들어, 단일 기본 창이 작성되는 간단한 Windows 프로그램을 고려하십시오. AC 버전은에 WNDCLASS[EX]전달 될 구조를 채운 RegisterClass[Ex]다음 CreateWindow[Ex]메시지 루프 를 호출 하고 입력합니다. 매우 간단하고 축약 된 코드는 다음과 같습니다.

WNDCLASS wc;
MSG      msg;

wc.style         = 0;
wc.lpfnWndProc   = &WndProc;
wc.cbClsExtra    = 0;
wc.cbWndExtra    = 0;
wc.hInstance     = hInstance;
wc.hIcon         = NULL;
wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wc.lpszMenuName  = NULL;
wc.lpszClassName = "MainWndCls";

RegisterClass(&wc);

CreateWindow("MainWndCls", "", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
             CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

while(GetMessage(&msg, NULL, 0, 0)){
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

C #의 동등한 프로그램은 한 줄의 코드 일 수 있습니다.

Application.Run(new Form());

이 한 줄의 코드는 거의 20 줄의 C 코드가 수행했던 모든 기능을 제공하며 오류 확인과 같은 몇 가지 기능을 추가합니다. 풍부하고 완전한 라이브러리 (일반적인 C 프로젝트에 사용 된 라이브러리와 비교)는 우리를 위해 많은 노력을 기울여 우리에게 짧아 보이지만 뒤에서 많은 단계를 포함하는 더 많은 코드 스 니펫을 작성할 시간을 자유롭게했습니다.

그러나 쉽고 빠른 코드 팽창을 가능하게하는 풍부한 라이브러리는 실제로 내 요점이 아닙니다. 우리의 작은 원 라이너가 실제로 실행될 때 실제로 일어나는 일을 검사하기 시작할 때 내 요점이 더 분명합니다. 언젠가는 재미를 위해 Visual Studio 2008 이상에서 .NET 소스 액세스활성화 하고 위의 간단한 한 줄로 들어가십시오. 당신이 보게 될 재미있는 작은 보석 중 하나는 다음에 대한 getter의 주석입니다 Control.CreateParams.

// In a typical control this is accessed ten times to create and show a control.
// It is a net memory savings, then, to maintain a copy on control.
// 
if (createParams == null) {
    createParams = new CreateParams(); 
} 

열 번 . A의 저장 무슨의 합과 거의 비슷 정보 WNDCLASSEX구조와 무엇에 전달 있어요 CreateWindowEx로부터 검색되는 Control클래스 열 시간 전에 그것이에 저장된 WNDCLASSEX에게 구조와 전달 RegisterClassExCreateWindowEx .

이 기본적인 작업을 수행하기 위해 실행되는 명령의 수는 C보다 C에서 2 ~ 3 배 더 높습니다.이 중 일부는 기능이 풍부한 라이브러리를 사용하기 때문에 반드시 일반화됩니다. 우리가 필요로하는 것을 정확하게 수행하는 단순한 C 코드. 그러나 그 중 일부는 .NET 프레임 워크의 모듈화 된 객체 지향적 특성이 종종 절차 적 접근 방식으로 피할 수있는 많은 반복 실행에 적합하다는 사실에 기인합니다.

C # 또는 .NET 프레임 워크를 선택하려고하지 않습니다. 또한 모듈화, 일반화, 라이브러리 / 언어 기능, OOP 등은 나쁜 것 입니다. 나는 C에서 개발 한 대부분의 작업을 나중에 C ++에서, 그리고 가장 최근에는 C #에서 수행했다. 마찬가지로 C 이전에는 주로 어셈블리를 사용했습니다. 그리고 각 단계가 "더 높은"언어로 진행됨에 따라 단기간 내에 더 나은, 유지 보수가 용이하고보다 강력한 프로그램을 작성합니다. 그러나 그들은 조금 더 느리게 실행하는 경향이 있습니다.


2
그것은 언어 문제가 아니라 API 문제입니다.
Arafangion

1
@ Arafangion : 당신이 말하는 것을 이해하지만 요점을 놓칩니다. 풍부한 기능을 갖춘 언어에 의해 기능이 풍부한 라이브러리가 활성화됩니다 (그리고 어떤 식 으로든 요구됨). 그리고 그것은 단지 도서관이 아닙니다. 라이브러리는 언어의 일반적인 사용법에 대한 예일뿐입니다. 모든 언어의 일반적인 응용 프로그램 코드는 일반적으로 해당 언어에서 일반적으로 사용되는 라이브러리와 유사합니다. 그것은 언어에 의해 촉진되는 사고 방식에 더 가깝습니다. 예를 들어, OO 언어는 일반적으로 OOP 지원이 적은 언어보다 개체를 할당, 구성, 파괴 및 할당 해제하는 데 더 많은 시간을 소비합니다.
P Daddy

나는 주어진 언어 선택이 일반적으로 특정 플랫폼과 라이브러리를 의미한다는 것을 인정할 것입니다. 예를 들어 리눅스에서는 C ++이고 안드로이드에서는 C ++와는 전혀 다릅니다. 또 다른 예는 Python입니다. CPython, Jython, PyPy 및 IronPython이 있습니다. 모두 매우 다른 라이브러리를 사용합니다.
Arafangion

그러나 이러한 Python을 사용하면 개발자는 특정 방식으로 응용 프로그램을 작성하는 경향이 있습니다. 예를 들어, 텍스트 파일에서 읽고 쓸 수 있으며 읽은 데이터로 새 개체를 만들 수 있습니다. 반면 C에서는 개발자가 구조체 배열을 한 번만 할당하고 이진 파일에서 해당 구조체를 읽고 쓸 가능성이 높습니다. 물론 이것은 단순히 사고 방식 에 대해 지적하려는 요점을 설명하려고 시도한 단순한 예입니다 .
P Daddy

6

Java를 제외하고 다른 컴파일러보다 C 컴파일러에 더 많은 노력을 기울 였다는 사실은 아무도 언급하지 않았다.

C는 거의 모든 다른 언어보다 이미 언급 된 여러 가지 이유로 극도로 최적화 할 수 있습니다. 따라서 다른 언어 컴파일러에 동일한 노력을 기울이면 C가 여전히 나올 것입니다.

노력보다 C보다 더 잘 최적화 할 수있는 후보 언어가 적어도 하나 있다고 생각하므로 더 빠른 이진을 생성하는 구현을 볼 수 있습니다. 제작자가 C보다 더 최적화 할 수있는 언어를 만들려고 노력했기 때문에 디지털 화성 D를 생각하고 있습니다.이 가능성이있는 다른 언어가있을 수 있습니다. 그러나 어떤 언어라도 컴파일러가 최고 C 컴파일러보다 몇 퍼센트 이상 빠를 것이라고 상상할 수 없습니다. 나는 틀리고 싶다.

실제 "낮은 교수형 과일"은 인간이 최적화하기 쉬운 언어로되어 있다고 생각합니다. 숙련 된 프로그래머는 모든 언어를 더 빠르게 만들 수 있습니다. 그러나 때로는 그렇게하기 위해 어리석은 일을하거나 부 자연스러운 구성을 사용해야합니다. 항상 노력을 기울일 것이지만, 좋은 언어는 프로그램 작성 방법을 정확하게 고집하지 않고도 비교적 빠른 코드를 생성해야합니다.

최악의 경우 코드가 빠르다는 점도 중요합니다 (적어도 나에게는). 웹에는 Java가 C보다 빠르거나 빠르다는 수많은 "증거"가 있지만 이는 체리 따기 예제를 기반으로합니다. 나는 C의 열렬한 팬은 아니지만 C로 쓰는 것은 잘 작동한다는 것을 알고 있습니다. Java를 사용하면 속도의 15 %, 보통 25 % 내에서 "아마도"실행되지만 경우에 따라 훨씬 더 나빠질 수 있습니다. 그것이 빠르거나 몇 퍼센트 안에 빠르는 경우는 대개 어쨌든 C에 최적화 된 라이브러리 코드에서 대부분의 시간을 소비하기 때문입니다.


5

이것은 실제로 약간의 허위 사실입니다. C 프로그램이 더 빠르다는 것은 사실이지만 특히 C 프로그래머가 그다지 능숙하지 않은 경우에는 항상 그런 것은 아닙니다.

사람들이 잊어 버리는 큰 눈부신 구멍은 프로그램이 GUI 프로그램의 사용자 입력과 같은 일종의 IO를 차단해야 할 때입니다. 이러한 경우 데이터를 처리 할 수있는 속도가 아니라 데이터가 들어오는 속도에 의해 제한되므로 사용하는 언어는 중요하지 않습니다. 이 경우 C, Java, C # 또는 심지어 Perl을 사용하더라도 중요하지 않습니다. 데이터가 들어오는 것보다 더 빨리 갈 수는 없습니다.

다른 중요한 것은 가비지 수집을 사용하고 적절한 포인터를 사용하지 않으면 가상 컴퓨터가 다른 언어로는 사용할 수없는 여러 가지 최적화를 수행 할 수 있다는 것입니다. 예를 들어, JVM은 조각 모음을 위해 힙에서 오브젝트를 이동시킬 수 있습니다. 따라서 다음 인덱스를 테이블에서 찾아 보지 않고 간단히 사용할 수 있으므로 향후 할당이 훨씬 빨라집니다. 최신 JVM도 실제로 메모리 할당을 해제 할 필요가 없습니다. 대신, 그들은 GC를 할 때 라이브 객체를 움직이고 죽은 객체에서 사용한 메모리는 본질적으로 무료로 복구됩니다.

이것은 또한 C에 대한 흥미로운 점을 제시하고 C ++에서는 훨씬 더 중요합니다. "필요하지 않으면 비용을 지불하지 않는다"는 디자인 철학이 있습니다. 문제는 당신이 원한다면 코를 통해 돈을 지불하게된다는 것입니다. 예를 들어 Java의 vtable 구현은 C ++ 구현보다 훨씬 나은 경향이 있으므로 가상 함수 호출이 훨씬 빠릅니다. 반면에 Java에서 가상 기능을 사용하는 것 외에는 선택의 여지가 없으며 여전히 비용이 많이 들지만 많은 가상 기능을 사용하는 프로그램에서는 비용이 절감됩니다.


1
"Java에서의 vtable 구현은 C ++ 구현보다 훨씬 나은 경향이 있으므로 가상 함수 호출이 훨씬 빠릅니다." 어떻게 지구상에서 MOV EAX보다 빨리 갈 수 있습니까, [ECX]; 전화 [EAX + someindex]; ? 조회하지 않고 함수를 호출 할 수 없다면, 이것은 최적으로 보입니다.
Frans-Willem

@Frans-JIT 컴파일러 (예 : Java HotSpot)는 주어진 객체가 항상 주어진 유형 인 경우 vtable 조회를 인라인 할 수 있습니다. C ++은 컴파일 타임에 동일한 정보를 알고 있으면이 작업을 수행하지만 x86 기계 명령어보다 Java 바이트 코드 로이 최적화를 수행하는 것이 더 쉽습니다.
Tom

6
@James- "I / O로 인해 성능이 저하된다"고 주장해도 "C가 다른 언어보다 빠릅니다"라는 문장은 무효화되지 않습니다. 그것은 눈부신 구멍이 아니라 밀짚 맨 논쟁입니다.
Tom

C의 문자열 처리 (및 표준 C 라이브러리)를 예로 사용하는 것이 더 좋았을 것입니다. C가 열악한 영역이기 때문입니다. 단순한 시작 코드로도 대부분의 다른 언어가 더 잘 작동합니다.
Donal Fellows

@DonalFellows mem * 함수는 일부 작업에서 str * 함수보다 빠를 수 있지만주의를 기울이면 문자열 처리가 효율적입니다. 특정 벤치 마크를 염두에 두셨습니까?
Jasen

4

도구와 라이브러리만큼 언어에 관한 것이 아닙니다. C에 사용 가능한 라이브러리 및 컴파일러는 최신 언어보다 훨씬 오래되었습니다. 이것이 느려질 것이라고 생각할 수도 있지만 반대입니다.

이 라이브러리는 처리 능력과 메모리가 중요한 시점에 작성되었습니다. 그들은 일을하기 위해 매우 효율적 으로 작성되어야 했습니다. C 컴파일러 개발자는 다른 프로세서에 대한 모든 종류의 영리한 최적화 작업에 오랜 시간을 보냈습니다. C의 성숙도와 폭 넓은 채택으로 인해 같은 연령의 다른 언어에 비해 큰 이점이 있습니다. 또한 C만큼 필요한 원시 성능을 강조하지 않는 최신 도구보다 C에 속도 이점을 제공합니다.


4

추상화가 부족하면 C가 더 빨라집니다. 출력문을 작성하면 무슨 일이 일어나고 있는지 정확히 알 수 있습니다. Java로 출력 명령문을 작성하면 클래스 파일로 컴파일되고 추상화 파일을 도입 한 가상 머신에서 실행됩니다. 언어의 일부로 객체 지향 기능이 부족하면 코드 생성 속도가 빨라집니다. C를 객체 지향 언어로 사용하는 경우 클래스, 무해 등의 모든 코딩을 수행하는 것입니다. 이는 코드의 양과 성능 저하로 모든 사람에게 충분히 일반화하여 작성해야합니다. 작업을 수행하는 데 필요한 것.


4

오래된 "C / C ++ Java보다 해석이 빠르므로 Java보다 빠릅니다"라는 신화는 여전히 살아 있습니다. 몇 년 전의 기사최신 기사 가 있지만 , 이것이 왜 항상 그렇지는 않는지 개념이나 측정으로 설명 합니다 .

현재 가상 머신 구현 (그리고 JVM뿐만 아니라)은 다양한 기술을 사용하여 프로그램 실행 중 수집 된 정보를 활용하여 코드가 실행될 때 동적으로 튜닝 할 수 있습니다.

  • 기계 코드에 빈번한 메소드 렌더링
  • 작은 방법을 인라인
  • 잠금 조정

대한 기타 조정의 다양한 코드가 실제로 무엇을하고 있는지 알고 기반으로, 그것은 실행중인되는 환경의 실제 특성에.


나는 자바 원시 성능면에서 훨씬 더 가까이 C에 그것을 가지고 지난 몇 년 동안 상당한 성능 향상을 만들었습니다하지만 그것이 있다는 사실 아래 사는 데 시간이 걸릴 것에 동의 너무 느린 위해 너무 오래. 그러나 어쨌든 누가 Java에 대해 이야기하고 있었습니까?
Robert Gamble

Java는 OP에서 참조하는 "다른 언어"입니까?
Robert C. Barth

@Robert : "다른 언어", 복수, C 이외의 특정 언어에 대한 언급은 없습니다. 어떻게하면 "Java"를 읽을 수 있습니까?
Robert Gamble

@Roberd : 질문에 직면하기 전에 게시 된 몇 가지 답변은 Java (또는 종종 인터프리터 또는 VM을 통해 구현되는 다른 언어)에 관한 이야기였습니다.
joel.neely

3
@Joel-대상 하드웨어를 아는 경우 C 또는 C ++에서 프로파일 가이드 최적화를 사용하여 런타임에 JVM이 수행 할 수있는 대부분의 최적화를 수행 할 수도 있습니다. 이는 차이를 만들어 내며 일반적으로 C와 C ++를 실행 중에 "학습"할 필요가 없기 때문에 리드를 다시 밀어 넣습니다.
Tom

4

가장 빠른 실행 코드는 수작업으로 제작 된 기계 코드입니다. 어셈블러는 거의 비슷할 것입니다. 둘 다 매우 낮은 수준이며 작업을 수행하는 데 많은 코드를 작성해야합니다. C는 어셈블러보다 약간 높습니다. 실제 머신에서는 여전히 매우 낮은 레벨로 사물을 제어 할 수 있지만 추상화가 충분하여 어셈블러보다 빠르고 쉽게 작성할 수 있습니다. C # 및 JAVA와 같은 다른 언어는 훨씬 더 추상적입니다. 어셈블러 및 기계어 코드를 저수준 언어라고하는 반면 C # 및 JAVA (및 기타 여러 언어)를 고수준 언어라고합니다. C는 때때로 중급 언어라고합니다.


당신의 대답을 읽는 동안, 단락 전체에서 두 단어 만이 금속을 당기는 자석처럼 내 눈을 끌고있었습니다. 이 단어는 단락에서 두 번 JAVA입니다. 모든 대문자로 쓰여지기 전에 그것을 본 적이
없으며,

3

다른 사람의 말을 들지 말고 코드의 성능 결정 부분에서 C와 선택 언어 모두에 대한 디스 어셈블리를 살펴보십시오. Visual Studio에서 런타임에 디스 어셈블리 창에서 디스 어셈블 된 .Net을 볼 수 있다고 생각합니다. windbg를 사용하여 Java에 까다로운 경우 가능해야하지만 .Net으로 수행하면 많은 문제가 동일합니다.

필요하지 않으면 C로 쓰는 것을 좋아하지 않지만 C가 아닌 다른 언어의 속도를 단순히 C에서 동일한 루틴을 분해하여 무시할 수 있다고 주장하는이 답변에서 제기 된 많은 주장을 생각합니다. 특히 성능에 중요한 응용 프로그램에서 일반적으로 사용되는 많은 양의 데이터가 포함 된 경우 더 높은 수준의 언어를 선택해야합니다. Fortran은 전문 분야에서 예외 일 수 있습니다. C보다 높은 레벨입니까?

JITed 코드와 네이티브 코드를 처음 비교했을 때 .Net 코드가 C 코드와 비교할 수 있는지 여부에 대한 모든 질문이 해결되었습니다. 추가적인 추상화 수준과 모든 안전 점검에는 상당한 비용이 듭니다. Java에 동일한 비용이 적용될 수는 있지만 성능에 중요한 부분을 시도해보십시오. (누구나 JITed Java에 대해 메모리에서 컴파일 된 프로 시저를 찾을만큼 충분한 지식이 있습니까? 확실히 가능해야합니다.)


2

1) 다른 사람들이 말했듯이 C는 당신을 위해 덜합니다. 초기화 변수, 배열 경계 검사, 메모리 관리 등이 없습니다. 다른 언어의 이러한 기능에는 C가 사용하지 않는 메모리 및 CPU주기가 필요합니다.

2) C가 덜 추상화되어 더 빠르다는 대답은 절반 만 맞습니다. 기술적으로 말하자면, 언어 X에 대해 "충분히 고급 컴파일러"를 사용한다면 언어 X는 C의 속도에 근접하거나 동일 할 수 있습니다. 순진한 컴파일러조차도 괜찮은 일을 할 수있는 어셈블리 언어에 직접. 파이썬과 같은 경우에는 가능한 유형의 객체를 예측하고 기계 코드를 즉석에서 생성하는 고급 컴파일러가 필요합니다 .C의 의미는 간단한 컴파일러가 잘 수행 할 수있을만큼 간단합니다.


2

좋은 시대로 돌아가서, 컴파일과 해석의 두 가지 언어가있었습니다.

컴파일 된 언어는 "컴파일러"를 사용하여 언어 구문을 읽고이를 CPU에서 직접 사용할 수있는 동일한 어셈블리 언어 코드로 변환했습니다. 해석 된 언어는 서로 다른 두 가지 체계를 사용했지만 기본적으로 언어 구문은 중간 형식으로 변환 된 다음 코드를 실행하기위한 환경 인 "통역사"에서 실행됩니다.

따라서 어떤 의미에서 코드와 기계 사이에 또 ​​다른 "계층"(인터프리터)이있었습니다. 또한 컴퓨터에서 항상 그렇듯이 더 많은 리소스가 사용됩니다. 통역사는 더 많은 작업을 수행해야했기 때문에 속도가 느 렸습니다.

최근에는 컴파일러와 인터프리터를 모두 사용하는 Java와 같은 하이브리드 언어가 더 많이 작동했습니다. 복잡하지만 JVM은 이전 인터프리터보다 더 빠르고 정교하며 최적화되어 있으므로 컴파일 된 코드에 가깝게 수행하는 시간이 지남에 따라 훨씬 더 나은 변화를 나타냅니다. 물론 최신 컴파일러에는 더 멋진 최적화 트릭이 있으므로 이전보다 더 나은 코드를 생성하는 경향이 있습니다. 그러나 대부분의 최적화는 항상 (항상 그런 것은 아니지만) 일부 상황에서 항상 모든 상황에서 더 빠르지는 않은 유형의 상충 관계를 만듭니다. 다른 모든 것들과 마찬가지로 무료는 제공되지 않으므로 옵티마이 저는 어딘가에서 자랑해야합니다 (종종 컴파일 타임 CPU를 사용하여 런타임 CPU를 절약하는 경우도 있음).

C로 돌아 가면 간단한 언어로, 최적화 된 어셈블리로 컴파일 한 다음 대상 컴퓨터에서 직접 실행할 수 있습니다. C에서 정수를 늘리면 CPU에서 하나의 어셈블러 단계 일 가능성이 높지만 Java에서는 그보다 훨씬 많은 결과가 발생할 수 있습니다 (가비지 수집도 포함 할 수 있음 : -) C는 기계에 더 가까운 추상화를 제공하지만 (어셈블러가 가장 가깝습니다) 결국에는 더 많은 작업을 수행해야하며 보호되거나 사용하기 쉽거나 오류 친화적이지 않습니다. 대부분의 다른 언어는 더 높은 추상화를 제공하고 더 많은 기본 세부 사항을 처리하지만 고급 기능과 교환하려면 더 많은 리소스가 필요합니다. 일부 솔루션을 일반화 할 때 더 넓은 범위의 컴퓨팅을 처리해야합니다.


"C에서 정수를 증가 시키면 CPU에서 하나의 어셈블러 단계 일 가능성이 큽니다."사실이 아닙니다. 이 정수가 CPU 레지스터에없는 경우 메모리에서 가져 와서 증가시키고 메모리에 다시 쓰려면 머신 코드가 있어야합니다. Java 코드를 실행할 때도 동일한 내용이 발생할 것으로 예상됩니다. 그리고 왜 "++ i"가 그 자체로 GC주기를 유발하는지에 대한 아이디어를 얻지 못했습니다.
quant_dev 2016 년

@quant_dev : "당신은 .. 메모리에서 가져 와서 증가시키고, 다시 써야합니다 ..." 그럴 수도 있고 아닐 수도 있고. 예를 들어 x86에는 메모리의 데이터에서 작동하는 명령어가 있습니다. ++i"add [ebp-8], 1"로 컴파일 할 수 있습니다. 페치, 증가, 저장은 여전히 ​​일어나지 않지만 CPU에 의해 처리되며 Paul이 말한 것처럼 단지 하나의 명령입니다.
P Daddy

... 이것은 단지 하나의 명령 일 수 있지만 여전히 데이터가 CPU에 도착하기를 기다리는 것을 포함하기 때문에 성능의 POV와 관련이 없습니다. 캐시 미스와 그 모든 것.
quant_dev 2016 년

아니요, 관련이 없다고 말하지는 않습니다. 하나의 CPU 명령어는 일반적으로 여러 CPU 명령어보다 적은 코드 바이트를 차지하므로 코드 세그먼트에서 더 나은 캐시 성능을 제공합니다. 하나의 CPU 명령어는 CPU의 파이프 라인에서 더 적은 공간을 차지하며 별도의 파이프 라인 단계에서 여러 단계 (페치, 증분, 저장)를 병렬로 처리 할 수 ​​있습니다. 실제로 파이프 라인의 다른 작업과 결합 할 수있는 작업의 일부는 건너 뛸 수도 있습니다. 예를 들어, 값 저장은 동일한 값의 후속로드로 병합 될 수 있습니다.
P Daddy

2

핫스팟 최적화 , 사전 컴파일 된 메타 알고리즘 및 다양한 형태의 병렬 처리 와 같은 고급 최적화 기술을 제외 하고 언어의 기본 속도 는 일반적으로 수행되는 작업을 지원하는 데 필요한 암시 적 배후 복잡성 과 밀접한 관련이 있습니다. 내부 루프 내에 지정되어야합니다 .

아마도 가장 분명한 것은 포인터 null검사 및 배열 경계에 대한 인덱스 확인과 같은 간접 메모리 참조에 대한 유효성 검사입니다 . 대부분의 고급 언어는 이러한 검사를 암시 적으로 수행하지만 C는 수행하지 않습니다. 그러나 이것이 반드시 다른 언어의 근본적인 한계는 아닙니다 . 충분히 영리한 컴파일러는 어떤 형태의 루프 불변 코드 모션을 통해 알고리즘의 내부 루프에서 이러한 검사를 제거 할 수 있습니다 .

C의 더 근본적인 장점 (그리고 밀접하게 관련된 C ++과 유사한 정도)은 스택 기반 메모리 할당 에 크게 의존하고 있으며, 이는 본질적으로 할당, 할당 해제 및 액세스에 빠릅니다 . C (및 C ++)에서 기본 호출 스택 은 기본 요소, 배열 및 집계 ( struct/class )의 .

C는 동적으로 할당 하는 기능을 제공하지만 임의의 크기와 수명의 메모리 (소위 '힙'사용)을 제공하지만 기본적으로 그렇게하지 않습니다 (스택이 대신 사용됨).

감탄스럽게도 때로는 다른 프로그래밍 언어의 런타임 환경 내에서 C 메모리 할당 전략을 복제 할 수 있습니다. C 또는 C ++로 작성된 코드를 JavaScript의 서브 세트로 변환하고 웹 브라우저 환경에서 거의 기본 속도로 안전하게 실행할 수있는 asm.js 에 의해 증명되었습니다 .


제쳐두고, C와 C ++가 속도를 위해 대부분의 다른 언어를 능가하는 또 다른 영역은 기본 기계 명령어 세트와 매끄럽게 통합 할 수있는 능력입니다. 주목할만한 예는 SIMD 내장 함수 의 (컴파일러 및 플랫폼에 따라 다름) 가용성 으로, 현재 거의 보편적으로 사용되는 병렬 처리 하드웨어를 활용하는 사용자 정의 알고리즘 구성을 지원하는 동시에 언어에서 제공하는 데이터 할당 추상화 (낮은 수준)를 활용합니다. 레벨 레지스터 할당은 컴파일러에 의해 관리됩니다).


1
C의이 메모리 할당 이점 중 일부는 영리한 컴파일러에 의해 다른 언어로 복제 될 수도 있습니다 ( 여기 참조 ). 그러나 나는 이것이 구조적으로 수행하기가 매우 어렵다는 인상을 얻었습니다. 특히 비 기본 데이터 유형의 경우. 이 게시물 은 Java에서 최적화로 스택 할당 할 수 있는 비 이스케이프 객체에 대한 아이디어를 언급합니다 .
nobar

2

왜 일부 언어가 더 빠르며 일부는 더 느린 지에 대한 링크에서 답변을 찾았습니다. 왜 이것이 C 또는 C ++가 다른 언어보다 빠른지에 대해 더 명확하게하기를 희망합니다 .C보다 빠른 다른 언어도 있지만 우리는 할 수 없습니다 그들 모두를 사용하십시오. 일부 설명-

Fortran이 여전히 중요한 주요 이유 중 하나는 빠르기 때문입니다. Fortran으로 작성된 번호 크 런칭 루틴은 대부분의 다른 언어로 작성된 동등한 루틴보다 빠릅니다. 이 영역에서 Fortran과 경쟁하는 언어 (C 및 C ++)는이 성능과 경쟁하기 때문에 사용됩니다.

이것은 질문을 제기합니다 : 왜? C ++과 Fortran이 빠른 이유는 무엇이며 Java 또는 Python과 같은 다른 인기있는 언어보다 우수한 이유는 무엇입니까?

해석 및 컴파일 프로그래밍 스타일과 제안하는 기능에 따라 프로그래밍 언어를 분류하고 정의하는 방법에는 여러 가지가 있습니다. 성능을 볼 때 가장 큰 단일 차이점은 해석 된 언어와 컴파일 된 언어 간의 차이입니다.

나누기는 어렵지 않다. 오히려 스펙트럼이 있습니다. 한쪽에는 포트란, C 및 C ++를 포함하는 그룹 인 전통적인 컴파일 된 언어가 있습니다. 이러한 언어에는 프로그램의 소스 코드를 프로세서가 사용할 수있는 실행 가능한 형식으로 변환하는 개별 컴파일 단계가 있습니다.

이 컴파일 프로세스에는 여러 단계가 있습니다. 소스 코드가 분석되고 구문 분석됩니다. 이 시점에서 오타 및 철자 오류와 같은 기본 코딩 오류가 감지 될 수 있습니다. 구문 분석 된 코드는 메모리 내 표현을 생성하는 데 사용되며,이 기능은 존재하지 않는 함수 호출 또는 텍스트 문자열에서 산술 연산을 수행하는 등의 실수를 감지하는 데에도 사용될 수 있습니다.

이 메모리 내 표현은 실행 코드를 생성하는 부분 인 코드 생성기를 구동하는 데 사용됩니다. 생성 된 코드의 성능을 향상시키기위한 코드 최적화는이 프로세스 내에서 다양한 시간에 수행됩니다. 코드 표현에 대해 높은 수준의 최적화가 수행 될 수 있으며 코드 생성기의 출력에는 하위 수준의 최적화가 사용됩니다.

실제로 코드를 실행하면 나중에 발생합니다. 전체 컴파일 프로세스는 단순히 실행할 수있는 것을 만드는 데 사용됩니다.

반대편에는 통역사가 있습니다. 인터프리터에는 컴파일러와 유사한 구문 분석 단계가 포함되지만 프로그램이 즉시 실행되는 직접 실행을 유도하는 데 사용됩니다.

가장 간단한 인터프리터는 언어가 지원하는 다양한 기능에 해당하는 실행 가능한 코드를 가지고 있습니다. 따라서 주어진 언어에 관계없이 숫자를 추가하고, 문자열을 조인하는 기능이 있습니다. 코드를 구문 분석 할 때 해당 기능을 찾아서 실행합니다. 프로그램에서 생성 된 변수는 이름을 데이터에 매핑하는 일종의 조회 테이블에 보관됩니다.

인터프리터 스타일의 가장 극단적 인 예는 배치 파일 또는 셸 스크립트와 같은 것입니다. 이러한 언어에서, 실행 코드는 종종 인터프리터 자체에 내장되지 않고 독립된 독립형 프로그램입니다.

그렇다면 왜 이것이 성능에 차이가 있습니까? 일반적으로 각 간접 계층은 성능을 저하시킵니다. 예를 들어, 두 개의 숫자를 추가하는 가장 빠른 방법은 프로세서의 레지스터에 해당 숫자를 모두 두어 프로세서의 추가 명령어를 사용하는 것입니다. 이것이 컴파일 된 프로그램이 할 수있는 일입니다. 변수를 레지스터에 넣고 프로세서 명령어를 활용할 수 있습니다. 그러나 해석 된 프로그램에서 동일한 추가를 수행하려면 추가 할 값을 가져오고 추가를 수행하기 위해 함수를 호출하기 위해 변수 테이블에서 두 개의 조회가 필요할 수 있습니다. 이 함수는 컴파일 된 프로그램이 실제 추가를 수행하는 데 사용하는 것과 동일한 프로세서 명령어를 잘 사용할 수 있지만 실제로 명령어를 사용하기 전에 수행되는 모든 추가 작업으로 인해 속도가 느려집니다.

더 알고 싶다면 소스 를 확인하십시오


1

일부 C ++ 알고리즘은 C보다 빠르며 다른 언어의 알고리즘 또는 디자인 패턴 구현은 C보다 빠를 수 있습니다.

사람들이 C가 빠르다고 말하고 다른 언어에 대해 이야기 할 때 일반적으로 C의 성능을 벤치 마크로 사용합니다.


2
"일부 C ++ 알고리즘이 C보다 빠릅니다"는 의미가 없습니다. 모든 "C ++ 알고리즘"은 C로 작성 될 수 있으며 그 반대도 가능합니다. 알고리즘은 언어에 구애받지 않습니다. C ++은 본질적으로 C에 기능을 추가합니다.이 새로운 기능 중 어느 것도 더 빠른 알고리즘을 만들지 않습니다 (아마도 작성하기는 쉽지만).
Joseph Garvin

1
고전적인 책책은 std :: sort algorithm입니다. std :: sort는 C의 정렬 알고리즘보다 빠릅니다. C에서 동일한 성능을 얻는 유일한 방법은 원하는 곳에서 매크로를 사용하거나 매크로를 사용하는 것입니다. 컴파일러는 최적화 할 정보가 더 적습니다.
Arafangion

1

최신 최적화 컴파일러를 사용하면 순수한 C 프로그램이 컴파일 된 .net 코드보다 훨씬 빠를 가능성은 거의 없습니다. .net과 같은 프레임 워크가 개발자에게 제공하는 생산성 향상을 통해 일반 C에서 몇 주 또는 몇 달이 걸리던 작업을 하루에 수행 할 수 있습니다. 개발자의 월급과 비교할 때 저렴한 하드웨어 비용과 결합하면 그저 길입니다 쓰기로 저렴 고급 언어로 물건을 느리게하고 하드웨어를 던지십시오.

Jeff와 Joel이 C를 "실제 프로그래머"언어라고 말하는 이유는 C에 손을 잡고 있지 않기 때문입니다. 자신의 메모리를 할당하고, 메모리를 할당 해제하고, 자신의 경계 검사를 수행해야합니다. 새로운 객체 (); 가비지 수집, 클래스, OOP, 엔터티 프레임 워크, LINQ, 속성, 특성, 필드 또는 이와 유사한 것은 없습니다. 포인터 산술과 포인터 역 참조 방법 등을 알아야합니다. 그리고 그 문제에 대해 포인터가 무엇인지 알고 이해하십시오. 스택 프레임이 무엇인지, 명령어 포인터가 무엇인지 알아야합니다. 작업중인 CPU 아키텍처의 메모리 모델을 알아야합니다. 마이크로 컴퓨터의 아키텍처에 대한 암묵적인 이해가 많이 있습니다 (일반적으로C에서 프로그래밍 할 때 C #이나 Java와 같은 프로그래밍 할 때 단순히 존재하지 않거나 필요하지 않은 마이크로 컴퓨터. 이 모든 정보는 컴파일러 (또는 VM) 프로그래머에게 오프로드되었습니다.


"문제가 더 많은 하드웨어"는 실제로 가능한 환경에서만 작동합니다. 임베디드 시장은 완벽한 반례입니다 (그리고 그것은 거대한 시장입니다).
Bob Somers

Jeff와 Joel은 임베디드 시스템이 아닌 비즈니스 시스템에 대해서만 블로그를 작성하므로 이것이이 질문의 맥락이라고 가정하는 것이 합리적입니다.
Robert C. Barth

1) .net 코드는 C 코드만큼 빠르게 실행됩니까? 실제로 C 프로그램을 작성한 적이 있습니까? 2) "문제가 발생하면 더 많은 하드웨어를 던진다"는 생각 때문에 1.3GHz 듀얼 코어 2GB 시스템이 Windows XP와 거의 일치하지 않는 반면 800MHz 512MB 시스템은 최신 버전의 Ubuntu를 사용합니다.
Robert Gamble

그렇습니다, 나는 C를 썼습니다. 사람들이 그것을 만드는 것만 큼 영광 스럽지는 않습니다. 그리고 프로젝트 비용이 너무 비쌉니다. 경제의 간단한 사례입니다. 메일과 웹 서버로 수년 동안 768MB RAM의 Pentium Pro 180MHz에서 Win2k를 실행했습니다. 잘 작동했습니다. 일화적인 증거는 아무것도 의미하지 않습니다.
Robert C. Barth

C는 "명예 롭지 않지만 빠르다. 동일한 작업을 수행하는 동안 C가 C #보다 거의 항상 빠르다는 것을 알기에 충분한 C 및 C # 코드를 작성했다. 일부 작업의 경우 고급 언어보다 개발하는 데 시간이 오래 걸리지 만 작업에 적합한 도구를 사용하는 것이 중요하며 때로는 C입니다.
Robert Gamble

1

자동 언어와 수동 언어의 차이점은 고급 언어가 추상화되어 자동화 된 것입니다. C / C ++는 수동으로 제어 및 처리되며, 오류 검사 코드도 수동 작업입니다.

C와 C ++는 컴파일 된 언어로, 어느 곳에서나 비즈니스를 수행 할 수있는 것은 아니며, 이러한 언어는 사용하는 하드웨어에 맞게 조정해야하므로 추가 계층을 추가해야합니다. C / C ++ 컴파일러가 모든 플랫폼에서 점점 일반화되면서 현재는 약간 희미 해지고 있습니다. 플랫폼간에 크로스 컴파일을 수행 할 수 있습니다. 여전히 모든 상황에서 실행되는 것은 아닙니다. 기본적으로 컴파일러 A에게 컴파일러 B와 동일한 코드를 다른 아키텍처로 컴파일하도록 지시합니다.

결론 C 언어는 이해하기 쉽지 않으며 추론하기위한 것이 아니며 시스템 언어라고도합니다. 그들은이 모든 높은 수준의 추상화 넌센스 이전에 나왔습니다. 이것이 또한 프론트 엔드 웹 프로그래밍에 사용되지 않는 이유입니다. 그것들은 단지 작업에 적합하지 않았으며, 기존 언어 툴로는 해결할 수없는 복잡한 문제를 해결하는 수단입니다.

이것이 바로 마이크로 아키텍처, 드라이버, 양자 물리학, AAA 게임, 운영 체제와 같은 미친 것들을 얻는 이유입니다 .C와 C ++가 적합합니다. 속도 및 수 크 런칭이 주요 영역입니다.



1

다음과 같은 여러 가지 이유가 있습니다.

  • 어셈블리 언어로 컴파일됩니다.
  • 정적으로 입력됩니다.
  • 가비지 콜렉션이 없습니다.
  • 오류 처리가 없습니다.
  • 많은 프로그래밍 언어가 새로운 기능을 추가합니다. C의 철학의 일부는 더 많은 기능을 추가하는 대신 일을 단순하게 유지하는 것입니다.

왜 객체 지향적이지 않기 때문에 더 빨라야합니까?
sb27

A) 객체 지향 프로그래밍은 가비지 수집이 필요합니다. B) 객체 지향 프로그래밍과 같은 큰 기능은 컴파일러에 복잡성을 더합니다.
Sapphire_Brick

A) 아닙니다. C ++ 또는 Rust를 참조하십시오. B) 예. 그러나 컴파일러는 새로운 최적화를위한 기회를 제공합니다.
sb27

A) Rust에는 컴파일 타임 가비지 수집이 있고 c ++에는 클래스에 대한 가비지 수집이 있으므로 소멸자가 있습니다. B) 최적화 된 복잡성은 여전히 ​​복잡합니다
Sapphire_Brick

A) 가비지 수집이 아니며 어셈블리에서 프로그램을 작성하더라도 메모리 관리를 수행해야합니다. B) 아니요. 더 추상화하면 옵티마이 저가 더 나은 가정을 할 수 있습니다.
sb27
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.