왜 미세한 성능과 효율성에 관심을 가져야합니까?


71

C / C ++ 페이지의 많은 질문과 답변은 마이크로 성능 문제 (예 : 간접 vs 직접 vs 인라인 함수의 오버 헤드) 또는 O (N 2 ) vs O (N log N) 알고리즘을 사용하여 특별히 또는 간접적으로 논의 합니다. 100 개의 아이템 목록.

나는 마이크로 성능에 대해 걱정하지 않고 매크로 성능에 대해 거의 걱정하지 않고 문제가 있음을 알지 않는 한 유지 관리하기 쉽고 안정적인 코드에 중점을 둡니다.

내 질문은 왜 많은 프로그래머들이 그렇게 많은 관심을 가지는가? 그것은 대부분의 개발자에게 정말로 문제가됩니까, 너무 걱정하지 않아도 될 정도로 운이 좋았습니까, 아니면 나쁜 프로그래머입니까?


5
+1, 일반적인 질문입니다.
iammilind

+1 좋은 질문입니다. 태그 2 개를 추가했습니다.

2
1) "조기 최적화는 모든 악의 뿌리"입니다. 2) 80 %의 시간이 코드의 20 % (80/20 규칙)에 사용됩니다.
James Khoury

2
나는 O (n * n) 예제에 대한 몇 가지 답변을 이야기합니다. 나는 100 개의 항목 목록을 명시 적으로 지정했지만 여전히 O (nlogn)이 더 낫다고 주장합니다. 프로그래머가 실제 현재의 요구 사항이 아닌 가능한 미래의 요구 사항으로 프로그래밍하고 있기 때문에이 미세 최적화 강박 관념입니까? (내가 그 말을들은 곳은 ...)
mattnz

5
@James Donald Knuth의 인용문은 "우리는 시간의 약 97 %라는 작은 효율성을 잊어야합니다. 조기 최적화는 모든 악의 근원"이라고 말합니다. 이 글타래에 3 %가 남았습니다.
StuperUser

답변:


14

실제로, 성능은 그 세부 수준에서 관리해야 할 문제가 아닙니다. 방대한 양의 데이터를 저장하고 조작 할 것임을 알고 있다면 상황을 주시 할 가치가 있지만, 그렇지 않으면 옳고 나아질 수 있습니다.

특히 세밀하게 제어 할 수있는 C 및 C ++에서 가장 쉬운 함정 중 하나는 너무 일찍, 너무 세밀하게 최적화하는 것입니다. 일반적으로 규칙은 다음과 같습니다. A) 문제가 발견 될 때까지 최적화하지 않고 B) 프로파일 러를 사용하여 문제 영역으로 입증되지 않은 것을 최적화하지 않습니다.

B)의 추론은 다음과 같습니다. 프로그래머는 성능 병목 현상이 어디에 있는지 예측하기에 악명이 높습니다. 프로파일 러를 사용하고 느린 부분을 최적화하거나 한 섹션의 코드를 너무 많이 호출하여 문제를 일으키는 경우 알고리즘을 변경하십시오.


6
다른 하나 : 한 번 실행되는 초기화 코드는 일반적으로 최적화가 필요하지 않으므로 다른 곳을보십시오.
Mike DeSimone

3
"한 번"빈도에 따라 다릅니다. 을 ./configure실행할 때 런타임의 최대 75 %가 스크립트가 실행하는 프로그램의 "초기화"코드에 소비 될 수 있다고 말합니다. 동적 연결에 25-50 %가 사용될 수도 있습니다.
R ..

12
규칙 A는 끔찍한 규칙입니다. 시스템의 아키텍처는 성능에 중요한 역할을하며 나중에 아키텍처를 파악할 경우 단순히 성능 요구 사항을 지원할 수없는 것이 기본입니다. 따라서 세부 사항을 전달할 수는 있지만 처음에 이것을 완전히 무시하는 것은 명백한 잘못입니다.
edA-qa mort-ora-y

3
@ edA-qa : 나는 그렇게 생각했지만, 수년에 걸쳐 성능 고려 사항이 문제가되기 전에 더 많은 프로젝트가 엉망이거나 실패했습니다. 성능 문제가있을 때마다 수정 프로그램은 비용이 적게 들고 며칠 또는 몇 주가 걸렸으며 개발 과정에서 다른 "버그"보다 더 많은 문제를 발견하지 못했습니다. 그러나 otehr 위험 항목과 마찬가지로 성능 원뿔을 프로젝트 초기에 식별하고 완화해야합니다.
mattnz

5
OP는 그렇게 많은주의를 기울 였는지 , OP가 다른 사람이 "걱정하지 마세요!"
red-dirt

54

나는 당신의 목록에있는 모든 것이 마이크로 최적화라고 생각합니다.

100 개 항목 목록에서 O (n * n) vs O (NlogN) 알고리즘 사용

내가 봐야 할 것 같아요. 물론, 그 목록은 현재 100 개 항목 이며 작은 n을 위해 모든 것이 빠르지 만 곧 동일한 코드가 몇 백만 줄 목록에 재사용 될 것이고 곧 코드는 계속 될 것입니다 합리적으로 작동합니다.

올바른 알고리즘을 선택하는 것은 결코 미세한 최적화 가 아닙니다 . 2 개월 또는 2 년 후에 동일한 코드가 어떤 종류의 데이터를 사용하는지 알 수 없습니다. 프로파일 러의 지침에 따라 쉽게 적용 할 수있는 "마이크로 최적화"와 달리 알고리즘 변경은 종종 새로운 알고리즘을 효과적으로 사용하기 위해 상당한 재 설계가 필요합니다. 예를 들어 일부 알고리즘에서는 입력 데이터를 이미 정렬해야하므로 데이터가 정렬 된 상태로 유지되도록 응용 프로그램의 상당 부분을 수정해야 할 수도 있습니다.


36
"올바른 알고리즘을 선택하는 것은 결코 미세한 최적화가 아닙니다"+1

9
나는 +1했지만 데이터 크기가 작을 때 최적의 알고리즘을 선택하는 것은 개발 시간, 프로그램 크기 및 메모리 사용에 해로울 수 있습니다. 포커 핸드를 정렬하는 경우 퀵 정렬, 스무딩 정렬 또는 병합 정렬을 정말로 작성 하시겠습니까? 간단한 삽입 정렬로 시작하거나 정렬 네트워크를 사용합니다.
R ..

8
재밌 네요 마이크로 최적화에 대한 스레드에서 많은 주석가가 답변을 마이크로 최적화합니다. )
안전

5
"곧 수백만 줄 목록에 동일한 코드가 재사용 될 것입니다.": 문제 도메인에 전적으로 달려 있습니다. 예 : 체스 알고리즘을 작성하는 경우 보드 크기가 변경되지 않을 것이라고 확신 할 수 있습니다. 자율 주행 차량을 프로그래밍하면 휠 수가 그렇게 빨리 증가하지 않습니다 .
nikie

3
나는 "올바른 알고리즘을 선택하는 것은 결코 마이크로 최적화가 아니다"라는 단어를 싫어한다. 왜냐하면 "올바른"이라는 단어의 본질을 감안할 때 그것은 명백히 사실이기 때문이다. 그러나 나는 당신의 의미가 실제로 "동의하지 않는 가장 빠르거나 가장 효율적인"알고리즘이라고 생각합니다. 구현하는 데 많은 시간이 걸리고 해당 세그먼트의 속도 나 공간이 중요하지 않은 경우 가장 효율적인 알고리즘을 선택하는 것은 잘못된 선택입니다.
케이시 패튼

18

얼마 전, 첫 직장에서 임베디드 시스템 용 코드를 작성했습니다. 이 시스템은 8086 마이크로 프로세서를 사용했으며 메모리가 제한적이었습니다. 우리는 인텔 C 컴파일러를 사용했습니다. 내가 구축 한 시스템은 3 차원 구조 배열에 액세스해야했습니다. 나는 책이 말한 것처럼 3 차원에 대해 malloc을 호출 한 다음 다음 차원에 행을 할당 한 다음 끝 노드에 대해 calloc을 작성했습니다.

그것은 꽤 복잡했습니다 (당시 저에게는). 곡선 피팅, 분산 분석 프로세스 제어 및 카이 제곱 분석을 수행해야했습니다. 우리를 위해 이것을 한 라이브러리는 없었습니다. 우리는 그것을 모두 써서 8086에 모두 맞아야했습니다.

시스템은 개처럼 달렸다. 빠른 프로파일 링 후 가장 큰 문제 중 하나가 할당 자라는 것을 알았습니다. 문제를 해결하기 위해 malloc에 ​​대한 모든 호출을 포기하고 하나의 큰 메모리 블록에 대한 자체 메모리 관리를 수행했습니다.


같은 직무에 대한 다른 경우에, 고객은 통계적 공정 제어 시스템에서 응답 시간에 대해 불평했습니다. 이전의 팀은 운영자가 신호와 트립 스위치를 결합하기 위해 부울 논리를 사용할 수있는 "소프트웨어 PLC"시스템을 설계했습니다. 그들은 오늘날 우리가 "도메인 특정 언어"라고 부르는 단순화 된 언어로 작성했습니다. 내 기억으로는 모습 ((A1 + B1) > 4) AND (C1 > C2)등등.

원래 디자인은 평가할 때마다 해당 문자열을 구문 분석하고 해석했습니다. 우리의 공정한 프로세서에서는이 작업에 많은 시간이 걸렸으며 프로세스 컨트롤러가 프로세스 실행 속도만큼 빠르게 업데이트 할 수 없었습니다.

나는 그것을 새롭게 보았고 런타임에 그 논리를 어셈블리 코드로 변환 할 수 있다고 결정했습니다. 한 번 파싱 다음 실행될 때 마다 응용 프로그램이 동적으로 생성 된 함수를 호출했습니다. 오늘날 일부 바이러스와 마찬가지로 일종의 추측입니다 (그러나 실제로는 모릅니다). 결과적으로 성능이 100 배 향상되어 고객과 상사가 정말 행복해졌습니다.

새 코드는 유지 관리가 쉽지 않았으므로 사용자 정의 컴파일러를 작성했습니다 . 그러나 성능 이점은 유지 관리 단점보다 훨씬 뛰어났습니다.


더 최근에는 동적으로 XML 작업을 구문 분석해야하는 시스템에서 작업하고있었습니다. 파일이 클수록 시간이 더 오래 걸립니다. 이것은 성능에 매우 민감했습니다. 구문 분석이 너무 느리면 UI를 완전히 사용할 수 없게됩니다.

이런 종류의 것들이 항상 떠 오릅니다.


그래서 ... 때로는 유지 관리하기 쉽고 쓰기 쉬운 코드를 원할 수도 있습니다. 때로는 빠르게 실행되는 코드를 원할 수도 있습니다. 트레이드 오프는 각 프로젝트에서 결정해야 할 엔지니어링 결정입니다.


9
모든 예제에서 나중에 최적화하는 데 드는 비용은 처음부터 빠른 코드를 작성하는 것보다 그리 높지 않았습니다. 따라서 더 느린 간단한 코드를 먼저 작성한 다음 필요한 부분을 모두 최적화하십시오.
코드 InChaos

6
@ CodeInChaos : 대답은 달리 주장하지 않습니다. OP의 질문에 "왜 마이크로 성능과 효율성에 관심을 가져야합니까?" 사전 최적화 문제는 다른 응답자에 의해서만 유추되었습니다.
webbiedave

12

큰 이미지를 처리하고 모든 픽셀을 반복하는 경우 성능 조정이 중요 할 수 있습니다.


2
+1-또한 고주파 금융, 모든 종류의 오디오 / 비디오 인코더 / 디코더, 시뮬레이션 및 모델링 (예 : 게임), CPU 스케줄러 및 메모리 관리자와 같은 시스템 전체 비트 등
Billy ONeal

3
CAN 중요하지만, IS 그렇게 될 그것을 증명 한 후에 만 중요 하고 당신이 문제가 생각하는 곳으로 그것을 프로파일했습니다. (힌트 : 아마 없을 것입니다.)
저의 정확한 의견

2
@ 정확한 의견 제시 : 실제로 이미지 처리의 경우 데이터 처리는 일반적으로 두 번째로 많은 시간을 소비합니다 (I / O가 여전히 가장 큼). 그러나 I / O를 최적화하려면 많은 비정상적이고 미친 디자인과 동료 프로그래머의 수용이 필요하며 때로는 개선하기가 불가능합니다. 그러나 처리 부분은 일반적으로 매우 병렬화가 가능하므로 쉽게 얻을 수있는 이점이 있습니다. VirtualDub 수준에 도달하지 않는 한 다른
교묘

12

문화 뒤에 숨은 이유 에 대해 조금 말씀 드리겠습니다 .

20 세보다 40 세에 가깝고 성인 시절을위한 프로그래밍을 해본 경험이 있다면 C ++이 실제로 도시에서 유일하게 게임이되었을 때, 데스크톱 앱은 표준이었고 하드웨어는 여전히 대역폭 / 성능 측면에서 소프트웨어가 크게 뒤떨어집니다.

  • 우리는 (> 2G) 파일 을 읽을 수 있도록 바보 같은 프로그래밍 트릭을 수행해야했습니다 ...
  • 우리는 실행 가능한 크기 에 대해 걱정했습니다 ...
  • 우리는 프로그램이 소비하는 메모리 양에 대해 걱정했습니다 ...
  • 우리는 정기적으로 알고리즘 시간 대 공간 절충 결정을 내 렸습니다 ...
  • 심지어 백 엔드에, 우리는 했다 괜찮은 없음을 처리하기 위해 아무것도 CGI의 C에서 프로그램 또는 C ++를 작성. RPS의 ... 몇 배 더 빠릅니다.
  • 우리는 delphi / c ++ / vb 간의 성능 장점에 대한 테스트를 수행했습니다!

아주 소수의 사람들은 오늘이 일에 대해 걱정할 필요.

그러나 10 년 전, 소프트웨어는 56kb 모뎀을 통해 다운로드되고 5 년 된 PC에서 실행되는 것에 대해 여전히 걱정해야했습니다. 4GB의 하드 드라이브, 200Mhz 프로세서 및 128Mb의 RAM을 생각해보십시오.

그리고 10 년 전의 서버? Dell의 "차세대"서버 가격은 2000 달러이며 1Ghz 펜티엄 프로세서 2 개 , 2Gb 또는 Ram, 20Gb 하드 드라이브가 함께 제공됩니다.

그것은 단순히 다른 야구 게임 이었고 10 년의 경험을 가진 (노력자가 대답 할 가능성이있는) 모든 "노인"엔지니어들은 그 환경에서 치아자릅니다 .


1
20 년의 추가 경험은 또한 최적화 프로세스를 여러 번 반복하여 번 마크를 받았으며 나중에 필요할 수도있는 일을 피하는 것을 의미합니다. 망치를 사용하는 동안 엄지 손가락을 많이 치지 않는 것과 같은 이유입니다.
Blrfl

1
루프 풀기 <shudder>
red-dirt

5
오늘날 대역폭, CPU 및 메모리가 무제한이라고 생각하는 모든 어린이들은 모바일 애플리케이션이 제대로 작동하지 않는다는 것을 알게되었습니다.
gbjbaanb

9

여기에 이미 10 가지 답변이 있으며 일부는 정말 좋습니다. 그러나 이것은 내 개인적인 애완 동물이기 때문에 ...

a) 간단한 솔루션보다 더 많은 시간이 걸리는 조기 최적화 b) 간단한 솔루션의 절반 크기와 절반의 복잡도를 가진 c) 더 많은 코드를 도입하고 c) 읽기 어려운 정보는 절대적으로 피해야합니다. 그러나 개발자가 std :: map 또는 std :: vector를 사용하도록 선택할 수 있고 조기 최적화보다 나쁘지는 않지만 나쁘지 않은 성능에 대한 순수한 무지에서 잘못된 컬렉션을 선택합니다. 오늘날 코드를 약간 변경하고, 가독성을 유지하고, 동일한 복잡성을 유지하면서 더 효율적으로 만들 수 있다면 어떨까요? 아니면 "조기 최적화"라고 부르겠습니까? 나는 많은 사람들이 어떤 식 으로든 그 생각을 포기하지 않을 것임을 발견했습니다.

내가 아주 작은 변화를 요구하는 "미세 최적화"를 조언 한 사람이었고, 당신은 "너무 일찍 최적화해서는 안됩니다. 그냥 작동 시키도록합시다. 우리는 그것을 바꿀 것입니다. 나중에 성능 문제가있는 경우 " 수정하기 전에 몇 번의 릴리스가 필요했습니다. 그리고 그렇습니다. 성능 문제였습니다.

초기 최적화는 좋지 않을 수 있지만, 사람들이 해당 코드가 수행 할 작업을 이해하고 코드를 작성하고 O (x) 표기법을 "최적화"로 표시하는 질문을 무시하지 않으면 매우 유익하다고 생각합니다. 지금 작성할 수있는 많은 코드가 있으며 성능에 대한 약간의 생각만으로도 80 %의 문제를 피할 수 있습니다.

또한 많은 성능 문제가 현재 환경에서 발생하지 않고 바로 발생하지 않을 것임을 고려하십시오. 때로는 한계를 뛰어 넘는 고객이 있거나 다른 개발자가 프레임 워크 위에 구축하기로 결정하고 개체 수를 10 배로 늘리려 고합니다. 지금은 성능에 관한 몇 가지 사항으로 인해 나중에 비용이 많이 드는 재 설계를 피할 수 있습니다. 그리고 소프트웨어가 공식적으로 출시 된 후에 문제가 발견되면 간단한 수정조차도 적용하는 데 20 배 더 비쌉니다.

결론적으로, 항상 성과를 염두에두면 좋은 습관을 기르는 데 도움이됩니다. 깨끗하고, 가능한 한 간단하고 체계적인 코드를 작성하는 것만 큼 중요합니다.


+1 : 이것은 Shrinkwrap 소프트웨어 및 상용 웹 사이트 를 개발하기 위해 고용 된 사람들의 고용 가능성 요소 중 하나입니다 . 예방은 고객의 저주보다 비용이 적게 듭니다.
rwong

6

나는 당신이보고있는 많은 것이 간단한 샘플링 오류라고 생각합니다. 사람들이 간단한 상황을 처리 할 때 코드를 작성하면 끝납니다. 특히 최적화가 필요한지 분명하지 않은 상황에서 최적화가 필요한 등 비교적 까다로운 문제를 처리 할 때 질문을합니다.

즉, 의심 할 여지없이 조기 최적화도 포함됩니다. 올바르게 또는 달리 C와 C ++는 퍼포먼스에 대한 명성을 가지고 있으며, 퍼포먼스에 관심이있는 사람들 (실제로 필요한 것만 큼 즐거움을 위해 최적화를 할 수있는 사람들 포함)을 끌어들이는 경향이 있습니다.


1
한 - 참고 : 대부분의 SO "성능"태그 질문은 아마 표본 오차의 일부입니다 : P
빌리 ONeal

3
나는 여기에 엄청나게 많은 조기 최적화 질문을 보게 될 것입니다 ... 많은 취미 프로그래머가 게임 작성이라는 아이디어로 시작한다는 사실에서 비롯된 것입니다. 초보자의 머리에 나쁜 생각을하는 게임 개발 관련 웹 사이트. :-)
R ..

4
당신이 까다로운 일을 처리 할 때, 자주는 까다로운 문제에서 휴식을 취하고 사용할지 여부에 대해 걱정 시간을 쓸데없는 일에 낭비하기 쉬운 것 i++또는++i
Carson63000

@ Carson63000 : 예, 샘플이 완전히 왜곡 될 수 있습니다. 또는 그들은 왜 operator ++컴파일하지 않은지 에 대한 질문에 대답하는 데 시간을 보냅니다 .
rwong

4

다른 답변 중 일부는 임베디드 시스템에 대해 언급 하고 있으며 이것을 확장하고 싶습니다.

예를 들어 집안의 보일러 컨트롤러, 간단한 포켓 계산기 또는 현대 자동차 내부의 수십 개의 칩과 같은 저가형 프로세서를 포함하는 많은 장치가 있습니다.

비용을 절약하기 위해 PC 또는 스마트 폰용 코드 만 작성한 사람들에게는 작은 양의 플래시 (코드 저장)와 RAM이있을 수 있습니다. 전력을 절약하기 위해 상대적으로 낮은 클럭 속도로 작동 할 수 있습니다.

예를 들어, STM32 마이크로 컨트롤러 제품군24MHz, 16KB 플래시 및 4KB RAM , 최대 120MHz, 1MB 플래시 및 128KB RAM으로 구성 됩니다.

이와 같은 칩용 코드를 작성할 때 코드를 가능한 효율적으로 만드는 것을 목표로하면 많은 시간이 절약됩니다. 분명히, 조기 최적화는 여전히 나쁜 생각입니다. 그러나 실무를 통해 일반적인 문제를 신속하게 및 / 또는 최소한의 리소스로 해결하고 그에 따라 코드를 작성하는 방법을 배웁니다.


1
임베디드 시스템에서 고려해야 할 좋은 점은 내가 직접 일하는 분야입니다. 이를 염두에두고 지난 몇 년간 나의 경험은 잘못 인도 된 최적화는 항상 시간 낭비라는 것입니다. 우리를 안내 할 도구가 없다면 문제 영역을 거의 찾지 못합니다
Jeff

2

하나는 시간의 99 %를 상관하지 않을 하나 개의 세부 원인이되는 병적 인 성능의 케이스에 실행될 때이 본질적으로 낮은 수준의 언어 인 병목 현상을, 하나는 실제로 직접 대부분의 다른과는 달리 (이 문제를 해결 할 수있는 기회를 가지고 언어); 그러나 물론 가장 효과적인 방법은 즉시 명백하지 않습니다. 따라서 이상하고 흥미로운 미세 최적화 질문의 절반이 여기에 요청되었습니다.

나머지 절반은 금속에 얼마나 가까이 갈 수 있는지 궁금한 사람들로부터 나옵니다. 결국 본질적으로 저수준 언어입니다 ...


+1 : 언어 나 플랫폼에 관계없이 "병리학 적 성능"이 전세계 모든 사람에게 발생할 수 있다는 점을 지적 할 가치가 있습니다. 테스트 및 분해를 읽기 위해 저수준 언어로 다시 구현할 수있는 능력은 더 많은 통찰력을 제공 할 수 있지만 항상 실행 가능한 솔루션을 제공하지는 않습니다. 예 : "어셈블리에서 할 수 있다는 것을 알고 있지만 부분 신뢰 환경에서 실행해야합니다!"
rwong

2

C 및 C ++를 다룰 때 성능은 항상 뜨거운 주제입니다. 얼마나 멀리 가야하는지에 관해서는 항상 ASM을 인라인하는 지점으로 미치거나 더 빠른 반복을 위해 포인터 산술을 사용할 수 있습니다. 그러나 전체 프로그램 개발 작업이 중단되도록 최적화하는 데 많은 시간을 소비하는 시점이 있습니다.

이러한 문제를 처리 할 때 프로그래머 성능과 코드 성능이 있습니다. 이 중 어느 것에 초점을 맞추면 항상 흥미로운 질문이 생길 것입니다. 결국 가장 중요한 질문은 사용자에게 얼마나 눈에 띄는가입니다. 사용자가 수백 또는 수천 개의 요소로 배열을 만드는 데이터로 작업합니까? 이 경우 작업을 빠르게 수행하기위한 코딩으로 인해 사용자는 프로그램의 표준 작업이 느리다고 불평 할 수 있습니다.

그런 다음 소량의 데이터로 작업 할 사용자가 있습니다. 정렬 및 파일 작업과 같은 작업을 수행하는 일부 파일은 성능이 약간 떨어지지 만 유지 관리가 더 쉬운 고급 기능을 사용하는 경우 사용자에게 눈에 띄지 않습니다.

이것은 당신이 겪을 문제의 작은 예일뿐입니다. 다른 문제에는 대상 사용자의 하드웨어가 포함됩니다. 임베디드 시스템을 다룬다면 사용자가 램을 가진 듀얼 코어 머신을 가지고 있다면 성능에 대해 훨씬 더 걱정해야 할 것입니다.


흠 .. 더 빠른 반복을 위해 포인터 산술을 사용하지 않습니다. 인덱스 기반이든 포인터 기반 반복이든 관계없이 루프 당 곱셈 및 명령어 추가입니다. 일반적으로 인덱스 기반 반복보다 명확하기 때문에 사용합니다.
Billy ONeal

포인터 산술은 w / e보다 빠르지 않습니다.

2

프로그래머가 왜 그렇게 신경 쓰는가? 성능 문제를 파악하기 전에 문제를 해결하고 추측 할 때 이해하지 못하는 등 머리를 채우는 바보 같은 아이디어가 있습니다 .

내 경험에는 미리 생각 해야 할 성능 문제가 있기 때문에 까다 롭습니다 . 그들이 무엇인지 알기 위해서는 경험이 필요합니다.

즉, 내가 사용하는 방법은 귀하의 방법과 유사하지만 동일하지는 않습니다.

  1. 가장 간단한 디자인으로 시작하십시오. 특히, 데이터 구조는 가능한 한 표준화되고 최소화되어야합니다. 피할 수없는 중복성이있는 한, 일관성을 유지하는 방법으로 알림을 부끄러워해야합니다. 일시적인 불일치를 용인하고 주기적으로 복구하는 것이 좋습니다.

  2. 프로그램이 개발 중일 때 성능 문제는 조용히 들어올 수 있기 때문에 성능 조정을 주기적으로 수행하십시오. 내가 사용하는 방법은 무작위로 일시 중지 됩니다.

여기의 드릴께요 예를 들어 무슨 뜻인지의.


1

솔직히 말해서, 그것은 당신의 목표가 무엇인지 그리고 당신이 전문적으로 프로그래밍 하든지 취미로 프로그래밍 하느냐에 달려 있습니다.

오늘날 현대 컴퓨터는 정말 강력한 기계입니다. 어떤 기본 작업을 수행하든, 마이크로 최적화를 시도하는지 여부에 관계없이 작업 속도가 매우 빠릅니다. 물론 물리 또는 화학과 같은 분야의 슈퍼 컴퓨팅과 같은 다른 작업을 수행하는 경우 원하는만큼 최적화 할 수 있습니다.

초기 MIT 프로그래머는 멋진 것을 만들기 위해 태어나지 않았습니다. 그들은 기존 알고리즘을 단순화하고 강화하기 시작했습니다. 그들의 자존심은 2 + 2를 기존 알고리즘보다 2 초 만에 4 개 줄 이도록하는 것이 었습니다 (이것은 단지 예일뿐입니다). 그들은 성능을 위해 TI-83 기계에서 적은 펀치 카드를 계속 사용하려고 노력했습니다.

또한 임베디드 시스템 용으로 프로그래밍하는 경우 마이크로 성능에주의를 기울여야합니다. 다른 디지털 시계보다 5 나노초 더 빠른 틱 디지털 클럭을 원하지 않습니다.

마지막으로, 당신이 애호가 프로그래머라면 프로그램이 빠르더라도 가장 작은 세부 사항을 최적화하는 데 아무런 해가 없습니다. 필요하지는 않지만 확실히 일할 수 있고 더 많은 것을 배울 기회가 있습니다. 소프트웨어에서 전문적으로 작업하는 경우, 꼭 필요한 경우가 아니라면 그러한 사치를 누릴 수 없습니다.


1
나는 취미 프로그래머가되는 것과 관련이 없다고 생각합니다. 당신이 전문적으로 무언가를하지 않는다고해서 반드시 세상에 모든 시간을 투자해야한다는 의미는 아닙니다. 더욱이 대부분의 애호가들은 대부분의 진정한 전문가가 할 수있는 것보다 잘못된 알고리즘을 선택하는 등 더 큰 실수를 할 것입니다. 또한 전문가는 아마도 취미보다 훨씬 더 많은 데이터를 처리하여 더 빠른 속도로 처리해야하는 제품을 개발하고 있으며 고객이 앱의 성능에 만족해야합니다. 애호가에게는 그러한 제약이 없습니다.
Billy ONeal

그들은 그렇지 않지만, 그들이 원한다면 단지 그들에게 일할 시간이 더 있습니다.

3
나는 반대를 주장 할 것이다. 전문가로 일할 수있는 하루가 8 시간 이상 있습니다. 취미 프로젝트를 위해 하루에 1 시간, 2 시간이 걸립니다.
Billy ONeal

1

100 개의 아이템리스트에서 O (N2) vs O (NlogN) 알고리즘 사용.

나는 최근 비슷한 상황에 있었다. 나는 아이템의 배열을 가졌다. 예상되는 경우 목록에 두 개 (!)의 항목이 있었고 최악의 경우에도 4 개 또는 8 개를 기대하지 않습니다.

그 목록을 정렬해야했습니다. std::sort정렬 네트워크 ( if실제로 많은 중첩 된 s)로 대체 하면 실행 시간의 많은 부분이 줄어 듭니다 (수는 기억하지 않지만 10-20 %와 같습니다). 이것은 미세 최적화 의 이점이며 코드는 절대적으로 성능이 중요합니다.

물론 프로파일 링 후에 만이 작업을 수행했습니다 . 그러나 요점은, C ++처럼 불편하고 복잡한 언어를 사용한다면 (과부하 해결을위한 복잡한 규칙은 말할 것도없고), 모든 이점을 누리고 싶다는 것입니다.


1

누적 에너지 사용

이 토론에서 항상 빠졌다고 생각하는 답이 하나 있습니다. 그리고 어느 정도 누적 된 에너지 사용량 을 귀찮게 합니다 .

물론, 프로그램을 고급 인터프리터 언어로 작성하고 간접적 인 레이어가있는 브라우저에서 실행하거나 루프가 0.001 초 대신 0.01 초가 걸리더라도 별 문제가되지 않을 수 있습니다. 아무도 눈치 채지 못할 것입니다. 즉, 개별 사용자 는 눈치 채지 못할 것입니다.

그러나 수만 또는 심지어 수백만 명의 사용자가 귀하의 코드를 사용하면 추가적인 비 효율성이 더해집니다. 툴이 하루에 10 초 동안 CPU가 휴면 상태에 들어 가지 못하게하고 백만 명의 사용자가이를 사용하는 경우 비효율적 인 알고리즘 은 하루에 추가 140kWh [1]를 소비했습니다.

나는 이것이 논의되는 것을 거의 보지 못하고 슬프다 고 생각합니다. Firefox와 같은 인기있는 프레임 워크 및 멋진 대화 형 웹 응용 프로그램의 경우 수치가 훨씬 더 나쁘다고 생각하며 연구하는 것이 흥미로울 것입니다.


[1] 방금 50 와트에 1 천만 초 곱했습니다. 정확한 수치는 많은 것에 달려 있습니다.


1
마법의 단어 "mobile"을 언급하여 바로 시작해야합니다. 데스크탑 플랫폼에서 실행하는 경우 초당 60 회 프레임을 그리는 데 1/100 초의 CPU 시간이 걸리는 응용 프로그램은 "충분히 빠릅니다". 성능을 10 배로 향상 시키면 사용자에게는 전혀 차이가 없습니다. 그러나 모바일 플랫폼에서 CPU 사용률이 90 %로 실행되는 응용 프로그램은 10 %로 실행하는 것보다 배터리가 훨씬 빨리 소모 될 수 있습니다.
supercat

1

때로는 여전히 강력한 성능 요구가있는 선형 시간보다 나을 수없는 알고리즘 만 있습니다.

예를 들어 모든 픽셀을 반복하지 않고 이미지 / 프레임을 기본 예제로 밝게 만들 수없는 비디오 처리가 있습니다. 자녀가 상속 한 속성을 나타내는 일종의 계층 구조를 사용하여 이미지 타일로 내려갈 수 있다고 가정합니다. 리프 노드의 경우 모든 픽셀을 렌더러로 루핑하는 데 더 많은 비용이 소요되며, 코드는 가장 미세하게 최적화 된 이미지 필터보다 유지 관리가 더 어려울 수 있습니다).

내 분야에는 그런 경우가 많이 있습니다. 나는 모든 종류의 정교한 데이터 구조 또는 알고리즘에서 이익을 얻는 것보다 모든 것을 만지거나 모든 것을 읽어야하는 선형 복잡성 루프를 더 많이 사용하는 경향이 있습니다. 모든 것을 만져야 할 때 건너 뛸 수있는 작업이 없습니다. 따라서이 시점에서 필연적으로 선형 복잡성을 처리하는 경우 반복 당 작업을 더 저렴하고 저렴하게 만들어야합니다.

따라서 필자의 경우 가장 중요하고 일반적인 최적화는 종종 데이터 표현 및 메모리 레이아웃, 멀티 스레딩 및 SIMD입니다 (일반적으로 후자의 두 가지 수행 능력에 영향을 미치기 때문에 데이터 표현이 가장 중요합니다). 나는 나무, 해시 테이블, 정렬 알고리즘 및 그와 같은 것들에 의해 해결되는 많은 문제를 겪고 있지 않습니다. 나의 일일 코드는 "각 일마다 무언가를해라" 라는 맥락에서 더 중요 합니다.

물론 최적화가 필요한시기 (더 중요하지 않은 경우), 마이크로 또는 알고리즘에 대해 이야기하는 또 다른 경우 입니다. 그러나 필자의 특별한 경우, 중요한 실행 경로에 최적화가 필요한 경우 멀티 스레딩, SIMD 및 메모리 레이아웃 재배치와 같은 마이크로 레벨 최적화 및 참조 지역 개선을위한 액세스 패턴과 같은 마이크로 레벨 최적화를 통해 10 배 이상의 속도 향상을 달성 할 수 있습니다. 예를 들어, 핫 / 콜드 필드 스 플리 팅의 혜택을받는 핫스팟을 찾을 정도로 버블 정렬을 인트로 소트 또는 기수 정렬 또는 2 차 복잡성 충돌 감지를 BVH로 대체하는 것은 그리 쉬운 일이 아닙니다.

이제 필자의 분야는 성능에 매우 중요한 (레이 트레이싱, 물리 엔진 등) 이미지를 렌더링하는 데 10 시간이 걸리는 느리지 만 완벽하게 정확한 레이트 레이서가 종종 대화식이지만 완전히 대화식이지만 쓸모없는 것으로 간주됩니다. 수밀 광선 / 삼각 교차점이 없기 때문에 광선이 사방으로 누출되어 가장 추악한 이미지를 출력합니다. 속도는 틀림없이 그러한 소프트웨어의 기본 품질 측정 기준일 수 있습니다. 아마도 어떤 점에 대한 정확성 이상일 수도 있습니다 ( "정확도"는 충돌이 발생하지 않는 한 모든 것이 근사하기 때문에 레이트 레이싱의 퍼지 아이디어이기 때문에). 이 경우 효율성을 미리 생각하지 않으면보다 효율적인 설계를 처리하기 위해 가장 비싼 설계 수준에서 실제로 코드를 변경해야합니다. 내가하지 않으면

게임은 내 것과 비슷한 또 다른 분야입니다. 게임이 슬라이드 쇼처럼 초당 1 프레임으로 실행되는 경우 게임 로직이 얼마나 정확한지 또는 코드베이스가 얼마나 유지 관리 가능하고 훌륭하게 설계되었는지는 중요하지 않습니다. 특정 분야에서는 속도가 부족하여 실제로 사용자가 응용 프로그램을 쓸모 없게 만들 수 있습니다. 게임과 달리 레이트 레이싱과 같은 영역에는 "충분히 좋은"메트릭이 없습니다. 사용자는 항상 더 빠른 속도를 원하며 산업 경쟁은 주로 더 빠른 솔루션을 찾는 데 있습니다. 게임이 경로 추적기를 사용하는 시점까지 실시간으로 충분하지 않을 것입니다. 그리고 VFX에는 여전히 충분하지 않을 것입니다. 아티스트는 수십억 개의 다각형을로드하고 30+ FPS에서 수십억 개의 입자 중 자체 충돌로 입자 시뮬레이션을 수행 할 수 있기 때문입니다.

이제는 편안하지만 성능에 대한 염려없이 스크립트 언어 (Lua)로 코드의 약 90 %를 작성합니다. 그러나 실제로 수백만에서 수십억 개의 항목을 반복 해야하는 비정상적으로 많은 양의 코드가 있으며, 수백만에서 수십억 개의 항목을 반복 할 때 순진한 단일 스레드 코드의 급격한 차이를 느끼기 시작합니다. 관련없는 데이터가 캐시 라인에로드되지 않는 연속 블록에 병렬로 실행되는 벡터화 된 코드와 비교할 때마다 반복적으로 캐시 미스가 발생합니다.


0

언급했듯이 마이크로 성능 문제에 대한 관심은 실제로 이러한 문제로 인해 발생하는 일부 문제를 설명하기 전에는 가치가 없습니다.


0

이 질문에 일반적으로 대답하는 것은 실제로 불가능합니다. 오늘날 구축되고있는 대부분의 소프트웨어는 내부 웹 사이트 및 LOB 응용 프로그램이며 이러한 종류의 프로그래밍에 대해서는 추론이 정확합니다. 반면에 장치 드라이버 나 게임 엔진과 같은 것을 작성하는 경우 최적화가 "조기 적"이 아닙니다. 하드웨어 제약 조건이 다른 매우 다른 시스템에서 소프트웨어가 실행될 가능성이 있습니다. 이 경우 성능을 위해 설계하고 차선책 알고리즘을 선택하지 않아야합니다.


정확히 내가 말하고 싶은 것. 모든 소프트웨어에는 응용 프로그램 도메인이 있으며 소프트웨어 외부에서 최적으로 작동하지 않아야합니다. 이런 의미에서, 조기 최적화는 잘못된 안내 완벽주의의 예입니다.
K.Steff 2016 년

0

나는 성능에 너무 관심이있는 프로그래머의 문제는 때로는 그의 인생에서 마이크로 퍼포먼스 코드를 작성해야 할 수도 있고, 매우 긴급하게, 배우고, 배우고, 배우고, 결국 그는 많은 것들과 트릭.

그리고 이제는 잊을 수 없으며 사전 측정 없이는 걱정할 필요가 없으며 빠른 코드를 사용하여 안전한쪽에 있습니다.

당신의 깊은 지식, 기술 및 몇 가지 트릭을 보여주고 배운 것을 재사용하는 것이 항상 좋습니다. 그것은 당신이 가치를 느끼게하고 시간은 배우고 가치있는 시간을 소비하게합니다.

때로는 내 인생에서 접두사 증가가 더 빠르다는 것을 알게되었습니다 ...

for (int i = 0; i < MAX; ++i)

... 접미사 증분보다 :

for (int i = 0; i < MAX; i++)

MAX가 낮 으면 문제가되지 않으며 루프에 실제 작업이 있으면 문제가되지 않습니다. 그러나 오늘날 컴파일러가 자체적으로 코드를 최적화하더라도 postfix 버전을 사용해야 할 이유는 없습니다.

아마도 성능 추구 자들은 '작업 및 판독 가능한 코드'와 같은 '작업 코드'를 작성하는 것 외에도 다양한 옵션의 지침을 얻기 위해 추가 목표가 필요할 수 있습니다.


0

너무 걱정하지 않아도 될 정도로 운이 좋았습니까, 아니면 나쁜 프로그래머입니까?

당신은 당신의 요구 사항에 관심이 있습니까? 성능이 필요하지 않은 경우 걱정하지 마십시오. 상당한 시간을 보내는 것은 고용주에게 장애가됩니다.

어느 정도까지는 성능이 항상 요구됩니다. 당신이 그것에 대해 생각하지 않고 칠 수 있다면, 당신은 그것에 대해 생각하지 않는 것이 정당합니다.

개인적으로 테스트를 통과하는 데 오랜 시간이 걸리면 성능에 의해 가장 많이 주도됩니다. 일련의 테스트가 통과되는 동안 5 분 정도 기다리기에는 너무 조급합니다. 그러나 그것은 일반적으로 테스트를 통해 해결됩니다.

내 질문은 왜 많은 프로그래머들이 그렇게 많은 관심을 가지는가? 실제로 대부분의 개발자에게 문제가됩니까?

그들이 얼마나 관심을 갖고 있는지 정당화되는 많은 프로그래머들이 있습니다. 그렇지 않은 많은 사람들이 있습니다. 그렇지 않은 사람들에 대해 이야기합시다.

프로그래머가 학교에서 가장 먼저 배우는 것 중 하나는 실제로 일을 수행하는 방법 후에 큰 O 표기법입니다. 그들 중 많은 사람들이 교훈을 제대로 배우고 따라서 n에 의해 극적으로 영향을받는 것에 초점을 맞 춥니 다. 다른 사람들은 수학을 얻지 못하고 일단 작동하면 빨리해야한다는 교훈을 빼앗아갑니다. 더구나,이 학생들 중 일부는 코드를 작동시키고 빠르게 작동시키는 것 외에 코드와 관련하여 중요한 것이 무엇인지 배우지 않습니다. 놓친 교훈 : 읽기 쉽고, 잘 디자인하고, 이유없이 놀아서는 안됩니다.

크 누스는 옳았다 : 조기 최적화는 모든 악의 근원이다. 그러나 일단 작동하면 다음 단계는 무엇입니까? 빨리요? 아니! 다음 단계는 읽을 수 있습니다. 읽을 수있는 것은 첫 번째, 다음, 중간 및 마지막 단계입니다. 불필요한 성능 최적화를 수행하는 많은 사람들이 버스에서 가독성을 떨어 뜨리고 있습니다.

어떤 사람들은 코드를 읽을 수 없다는 점에서 이상한 스릴을 얻습니다. 그들은 다른 사람들이 만든 코드를 이해하기가 힘들어 보였으므로 이제 돈을 돌려야합니다.

나는 이것을하기 때문에 이것을 알고있다. 한 번만 읽을 수없는 한 줄 부울 식으로 구조를 읽을 경우 완벽하게 읽을 수있는 5 줄을 리팩터링하고 너무 작고 위협적인 것을 만들 수 있기 때문에 인상을 기대하는 교수에게 자랑스럽게 보냈습니다. 내가 기대했던 칭찬을 얻지 못했습니다.

코드를 읽을 수 있으면 나중에 쉽게 만들 수 있습니다. 그래서 Knuth는 "필요하지 않은"것이 아니라 "조기"를 강조합니다. 확실하기 때문에 빠를수록 좋습니다. 그러나 당신이 그것을 위해 무엇을 희생 하느냐에 따라서 만 더 좋습니다. 따라서 희생을하기 전에 실제로 필요한 성능을 알 때까지 기다리십시오. 일단 가버린 후에는 되돌릴 수 없기 때문에 가독성을 희생적으로 희생하십시오.

가독성을 넘어서는 소프트웨어 디자인의 전 세계입니다. 이 사이트의 내용 일부는 디자인까지 무엇을해야하는지 전혀 모른다. 그래서 그들은 디자인에 깊은 인상을 줄 수 없기 때문에 사람들이 단서가 없다고 말할 수 없도록 엉망진창을 만듭니다. 아무도 코드를 수정하지 않았으므로 올바른 코드 여야합니까?

일부의 경우 성능은 원하는대로 수행 할 수있는 모든 변명입니다. 프로그래머에게는 많은 힘과 자율성이 있습니다. 그들에게 신뢰가 주어졌습니다. 신뢰를 남용하지 마십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.