최적화가 조기에 이루어지지 않아 악이 아닌 것은 언제입니까?


75

"조기 최적화는 모든 악의 근원"은 우리 모두가 듣거나 읽은 것입니다. 소프트웨어 개발의 모든 단계 (높은 수준의 설계, 세부 설계, 높은 수준의 구현, 세부 구현 등)에서 어떤 종류의 최적화가 조기에 이루어지지 않았는지 궁금한 점은 어두운면을 넘어 가지 않고 고려할 수있는 최적화 정도입니다.



답변:


116

경험을 바탕으로 할 때? 악하지 않다. "X를 할 때마다 성능에 치명적인 타격을 입었습니다. 이번에는 X를 완전히 최적화하거나 피할 계획입니다."

상대적으로 고통이 없을 때? 악하지 않다. "Foo 또는 Bar로 이것을 구현하는 것은 많은 작업을 필요로하지만 이론 상으로는 Bar가 훨씬 더 효율적이어야합니다. Bar 's Bar."

끔찍하게 확장되는 엉터리 알고리즘을 피할 때? 악하지 않다. "우리의 기술 책임자는 우리가 제안한 경로 선택 알고리즘이 팩토리얼 타임으로 실행된다고 말합니다. 그것이 의미하는 바는 확실하지 않지만, 그녀는 그것을 고려하기 위해 seppuku를 커밋 할 것을 제안합니다. 다른 것을 고려해 봅시다."

악은 당신이 실제로 존재하지 않는 많은 시간과 에너지 해결 문제를 소비함으로써 발생합니다. 문제가 분명히 존재하거나 팬텀 의사 문제가 싸게 해결 될 때, 악은 사라집니다.


Steve314Matthieu M. 은 고려해야 할 의견에서 점수를 올립니다. 기본적으로, 어떤 종류의 "무통"최적화는 그저 제공하는 사소한 성능 업그레이드가 코드 난독 화의 가치가 없거나, 컴파일러가 이미 수행하고있는 개선 사항을 복제하고 있거나, 또는 둘 다이기 때문에 그만한 가치가 없습니다. 너무 똑똑하지 않은 비 개선의 좋은 예는 주석을 참조하십시오.


22
때로는 팬텀 문제를 쉽게 해결하는 것이 여전히 약간 악합니다. 코드를 읽기 어렵고 유지하기가 더 어려울 수 있기 때문입니다. 그리 어렵지는 않지만 쉬운 해결책은 아니지만 때로는 여전히 관련성이 있습니다. 예를 들어 어떤 사람들은 인식하지 못하고 유용한 컴파일러라면 어쨌든 적용 할 수있는 영리한 비트 트릭을 사용하고있을 것입니다.
Steve314

26
나는 Steve가 여기에 동의하는데, 때때로 "최적화"는 그만한 가치가 없는데, 특히 컴파일러가 너무 나쁘기 때문이다. 예 ? i부호없는 경우 i / 2로 대체 할 수 있습니다 i >> 1. 더 빠릅니다. 그러나 그것은 또한 더 비밀입니다. 그러나 최악의 점은 컴파일러가 어쨌든 그렇게 할 것이므로 소스 코드를 난독 화하는 이유는 무엇입니까?
Matthieu M.

19
@Larry : 나는하지 않았으므로 좋은 예라고 생각합니다.
Joris Meys

18
그들은 코드의 readabiliy / maintainabiliy에 영향을 미칠 경우 내보기, 최적화, 심지어 간단한 것들에서, 또한 악을 간주되어야 하고 실제 성능 측정을 기반으로하지 않습니다.
Bart van Ingen Schenau

14
@ 매튜 : 그들에게 무엇을 가르쳐? 더럽고 불필요한 트릭? 왜? 경우 프로파일은이 것을 보여준다 i/2참 핫 스폿하고있다 (믿을 만의 가정하자) i>>1빨리 만드는, 그래서 그것을 할,이 프로파일 링이 빠르다는 것을 보여 주었다 거기에 코멘트를 넣어. 이것이 실제로 어디에서나 필요 하다면 (Mathieu가 말했듯이 컴파일러가 스스로 할 수있을만큼 똑똑해야하기 때문에) 초보자는 무언가를 배우지 않을 것입니다 (아마도), 왜 플러그를 하시겠습니까? 불필요 한 민속으로 그들의 머리?
sbi

38

응용 프로그램 코드는 필요한만큼만 양호 해야 하지만 라이브러리 사용 방법을 알 수 없으므로 라이브러리 코드 는 가능한 한 양호해야합니다. 따라서 라이브러리 코드를 작성할 때는 성능, 견고성 또는 기타 범주에 관계없이 모든 측면에서 우수해야합니다.

또한 응용 프로그램설계 할 때와 알고리즘선택할 때의 성능 을 고려해야합니다 . 성능을 발휘하도록 설계되지 않으면 해커가 어느 정도 성능을 발휘할 수 없으며 마이크로 최적화가 우수한 알고리즘보다 중요하지 않습니다.


5
라이브러리 코드는 "가능한 한"노력하고 있는지 또는 목표가 무엇인지 문서화해야합니다. 소비자가 적절한 경우에만 코드를 사용하는 경우 코드가 유용하기 위해 절대적으로 최적 일 필요는 없습니다.
supercat 2018 년

1
죄송하지만 "모든 측면에서 우수합니다"라는 말은 과도하게 엔지니어링 된 것 같습니다. 또한 현실이 아닐 수도 있습니다. 인생은 항상 트레이드 오프에 관한 것입니다.
sleske 2016 년

1
설계 단계를 강조하기 위해 +1; 고의로 그 이점을 평가하고 있다면 조기에 그렇지 않습니다.
Nathan Tuggy

반대로, 도서관이 어떻게 사용 될지 모른다면 도서관 개선에 시간을 투자하는 것이 비즈니스 가치를 지니고 있는지는 모릅니다. 그래서 그것은 거의 논쟁이 아닙니다.
RemcoGerlich

25

어떤 종류의 최적화가 조숙하지 않은가?

알려진 문제의 결과로 오는 종류.


17

최적화가 조기에 이루어지지 않아 악이 아닌 것은 언제입니까?

선과 악이 무엇인지 말하기는 어렵습니다. 누가 그 권리를 가지고 있습니까? 우리가 자연을 살펴보면, 우리의 유전자를 자손에게 전달하는 것을 포함하는 "생존"의 광범위한 정의로 생존을 위해 프로그램 된 것 같습니다.

따라서 최소한 기본 기능과 프로그래밍에 따르면 최적화는 재생산 목표와 일치 할 때 나쁘지 않습니다. 남자들에게는 금발, 갈색 머리, 빨간 머리, 많은 사랑스러운 사람들이 있습니다. 소녀들에게는 남자들이 있고 그들 중 일부는 괜찮은 것처럼 보입니다.

아마도 우리는 그 목적을 향해 최적화해야하고 프로파일 러를 사용하는 데 도움이됩니다. 프로파일 러를 사용하면 핫스팟 및 그 원인에 대한 자세한 정보를 제공 할뿐만 아니라 최적화 및 시간의 우선 순위를보다 효과적으로 지정할 수 있습니다. 이를 통해 생식과 추구에 더 많은 자유 시간을 보낼 수 있습니다.


3
누군가가이 오래된 밤에 신선한 음식을 가져 오는 것을 보는 것은 상쾌합니다. Knuth의 전체 인용문을 읽는 것뿐입니다. 단 한 문장도 아닙니다.
Robert Harvey

1
@RobertHarvey 나는 거기에 약간의 애완 동물이 있습니다. 왜냐하면 많은 사람들이 그 한 문장을 인용하는 것처럼 보이므로 너무 중요한 상황 정보가 그 과정에서 길을 잃었습니다. 나는 약간의 랜티를 받았기 때문에 그것이 훌륭한 대답인지 확실하지 않습니다. :-D

14

전체 인용 최적화 조기하지 않을 때 정의한다 :

훌륭한 프로그래머는 그러한 추론을 통해 만족에 빠지지 않을 것이며, 중요한 코드를주의 깊게 살펴 보는 것이 현명 할 것입니다. 그러나 그 코드가 식별 된 후에 만 . [강조 광산]

중요한 코드는 여러 가지 방법으로 식별 할 수 있습니다. 중요한 데이터 구조 또는 알고리즘 (예 : 많이 사용되거나 프로젝트의 "핵심")은 주요 최적화를 제공하고 많은 사소한 최적화는 프로파일 러를 통해 식별됩니다.


6
예 ... 임의의 함수 호출에 걸리는 시간을 90 % 줄이는 것이 좋습니다.하지만 앱이 실제로 시간의 80 %를 소비하는 코드를 살펴보면 더 큰 영향을 줄 수 있습니다. 거기에 몇 퍼센트.

11

경험에 따라 항상 "충분히 좋은"솔루션을 선택해야합니다.

최적화는 "필요한 것보다 더 복잡한 코드를 작성하여 더 빨리 만들 수있다"는 것을 의미하기 전에 실제로 필요하다는 것을 알기 때문에 코드를 필요 이상으로 복잡하게 만듭니다. 복잡성은 일을 어렵게 만들어서 좋은 일이 아닙니다.

즉, 간단한 정렬을 수행 할 때는 "복잡하게 디스크로 스왑하여 100Gb 파일을 정렬 할 수 있습니다"정렬 루틴을 선택해서는 안되지만 처음에는 간단한 정렬을 선택해야합니다. 맹목적으로 버블 정렬을 선택하거나 "모든 항목을 무작위로 골라 순서가 맞는지 확인하십시오. 반복하십시오." 거의 좋지 않습니다.


3

내 일반적인 규칙 : 최적화가 필요한지 확실하지 않다고 가정하십시오. 그러나 최적화해야 할 때를 명심하십시오. 그래도 미리 알 수있는 몇 가지 문제가 있습니다. 일반적으로 좋은 알고리즘과 데이터 구조를 선택해야합니다. 예를 들어 컬렉션의 멤버 자격을 확인해야하는 경우 특정 유형의 집합 데이터 구조가 필요할 것입니다.


3

내 경험상, 자세한 구현 단계에서 답은 코드를 프로파일 링하는 것입니다. 무엇이 더 빨라야하고 무엇이 허용 될 수 있는가를 아는 것이 중요합니다.

성능 병목 현상이 정확히 어디에 있는지 아는 것도 중요합니다. 전체 실행 시간의 5 % 밖에 걸리지 않는 코드 부분을 최적화하면 아무런 효과가 없습니다.

2 단계와 3 단계는 조기 최적화에 대해 설명합니다.

  1. 작동하게 만들다
  2. 테스트. 충분히 빠르지 않습니까? 프로필을 작성하십시오 .
  3. 2 단계의 데이터를 사용하여 코드의 가장 느린 섹션을 최적화하십시오.

단계 0을 잊어 버렸습니다. 시작부터 합리적인 성능을 기대할 수 있도록 응용 프로그램을 올바르게 설계하십시오.
Robert Harvey

자세한 구현 단계에 대해서만 이야기했습니다.
Gorgi Kosev

1
3 단계에 대한 질문입니다. 아주 가장 좋은 대답은 다른 접근법을 찾아서 처음에는 느린 코드를 사용하지 않는 것입니다.
Loren Pechtel

1
올바른 데이터 구조를 선택하십시오.
jasonk

3

하드웨어 플랫폼과 같이 변경하기 어려운 것을 선택할 때는 최적화되지 않습니다.

데이터 구조 선택은 좋은 예입니다. 기능적 및 비 기능적 (성능) 요구 사항을 모두 충족시키는 데 중요합니다. 쉽게 변경되지는 않지만 앱의 다른 모든 것을 구동합니다. 데이터 구조는 사용 가능한 알고리즘 등을 변경합니다.


3

이 질문에 대답하는 한 가지 방법 만 알고 있으며 이는 성능 조정 경험을 얻는 것입니다. 즉, 프로그램을 작성하고 프로그램 을 작성한 속도를 높이고 반복적으로 수행하십시오. 한 가지 예가 있습니다.

대부분의 사람들이 저지르는 실수는 다음과 같습니다 . 실제로 실행 하기 전에 프로그램을 최적화하려고 합니다. 그들이 실제로 실무 경험이 많지 않은 교수로부터 프로그래밍 과정을 수강했다면 그들은 큰 색의 안경을 갖게 될 것이며, 그것이 전부 라고 생각할 것입니다 . 사전 최적화에서 모두 동일한 문제입니다. **

누군가가 말했다 : 먼저 그것을 올바르게 한 다음 빨리 만드십시오. 그들은 옳았다.

그러나 이제는 키커를 위해 : 만약 당신이 이것을 몇 번한다면, 당신은 속도 문제를 일으키는 이전에했던 바보 같은 일들을 인식하고, 본능적으로 그것들을 피합니다. (클래스 구조를 너무 무겁게 만들고, 알림으로 늪에 빠지거나, 함수 호출의 크기를 시간 비용과 혼동하고, 목록이 계속되는 등의 것들 ...) 당신은 본능적으로 피할 수 있지만 덜 보이는 모양을 추측합니다. 경험 : 조기 최적화!

그래서이 바보 같은 논쟁은 계속되고 있습니다 :)

** 그들이 말하는 또 다른 것은 컴파일러가 너무 좋고 오늘날 기계가 너무 빠르기 때문에 더 이상 걱정할 필요가 없다는 것입니다. (KIWI-Iron로 죽여라.) 기하 급수적 인 소프트웨어 성능 저하를 보상 할 수있는 기하 급수적 인 하드웨어 또는 시스템 속도 향상 (아주 똑똑한 열심히 일하는 엔지니어가 수행)이 없습니다 (이러한 생각을하는 프로그래머가 수행).


2

요구 사항 또는 시장이 구체적으로 요구할 때.

예를 들어 대기 시간이 짧기 때문에 대부분의 금융 응용 프로그램에서 성능은 필수입니다. 거래되는 계측기의 특성에 따라 최적화는 고급 언어의 비 잠금 알고리즘 사용에서 저급 언어 사용 및 하드웨어 자체에서 주문 일치 알고리즘 구현 (예 : FPGA 사용)과 같은 극단적 인 것까지 진행될 수 있습니다. ).

다른 예로는 일부 유형의 내장 장치가 있습니다. 예를 들어 ABS 브레이크를 사용하십시오. 우선 안전이 있습니다. 브레이크를 밟으면 차가 느려집니다. 그러나 성능도 있으므로 휴식을 취할 때 지연을 원하지 않을 것입니다.


0

성능으로 인해 시스템의 "소프트 실패"(작동하지만 여전히 쓸모없는)를 초래하지 않는 것을 최적화하는 경우 대부분의 사람들은 최적화 조기 호출을합니다.

실제 사례.

  • 거품 정렬을 실행하는 데 20ms가 걸리는 경우 1ms 빠른 정렬로 최적화해도 성능이 2000 % 향상 되었음에도 불구하고 의미있는 방식으로 전체 유틸리티가 향상되지는 않습니다.

  • 웹 페이지를로드하는 데 20 초가 걸리고이를 1 초로 줄이면 웹 사이트의 유틸리티가 0에서 거의 무한대로 증가 할 수 있습니다. 기본적으로 너무 느려서 고장난 것이 이제 유용합니다.


프로그램 과정에서 정렬이 1000 번 호출되는 경우 20ms에서 1ms로 최적화하는 것이 중요합니다.
Beefster

0

조기 최적화가 아닌 최적화에는 어떤 것이 있습니까?

응용 프로그램의 알려진 성능 문제를 해결하는 최적화 또는 응용 프로그램이 잘 정의 된 승인 기준을 충족 할 수 있도록하는 최적화입니다.

확인 된 후에 수정 사항을 설정하는 데 시간이 걸리고 성능 이점이 측정되어야합니다.

(즉,이 코드는 느릴 수 있다고 생각합니다. 대신 Y를 사용하도록 X를 변경하면 더 빠릅니다.)

나는 코드를 느리게 만드는 많은 이른 "최적화"에 직면했다.이 경우, 나는 '생각하지 않는다'는 의미로 조기 복용하고있다. 성능은 최적화 전후에 벤치마킹해야하며 실제로 성능을 향상시키는 코드 만 유지해야합니다.


0

"조기 최적화는 모든 악의 근원"은 우리 모두가 읽거나 읽은 것입니다

참된. 불행히도 그것은 모든 시간 동안 가장 악의적으로 사용되는 프로그래밍 따옴표 중 하나입니다. 도널드 크 누스 (Donald Knuth)가 밈을 만들었으므로 따옴표에서 원래 컨텍스트를 추가하는 것이 좋습니다.

우리는 시간의 97 % 정도라는 작은 효율성을 잊어야합니다. 조기 최적화는 모든 악의 근원입니다. 그러나이 중요한 3 %의 기회를 포기해서는 안됩니다. ... 좋은 프로그래머는 ... 중요한 코드를주의 깊게 살펴 보는 것이 현명 할 것입니다. 코드가 확인 된 후에 만 ​​가능합니다. ... 측정 도구를 사용해온 프로그래머의 보편적 경험은 직관적 인 추측이 실패한다는 것입니다.

Knuth는 런타임에서의 실행 속도에 대해 구체적으로 이야기 했습니다 .

.. 프로그래머는 프로그램의 중요하지 않은 부분의 속도 에 대해 생각하거나 걱정하는 데 많은 시간을 낭비 합니다.

또한 그는 1974 년에 실행 속도와 프로그램의 유지 관리 성 (고속-유지 관리가 불가능한)간에 프리미엄과 음의 상관 관계가있는 기계 리소스가 현재보다 더 강력했을 때이 기사를 썼습니다.

도널드 크 누스 (Donald Knuth)에 따르면, 문제가 파악 되면 (프로파일 링 중에 이상적으로 측정되고 정확히 지적 된) 심각한 성능 병목 현상이 해결되면 최적화가 조기에 완료되지는 않습니다 .

앞서 말했듯이 "조기 최적화"는 가장 악의적으로 잘못 사용되는 밈 중 하나이므로 조기 최적화가 아니지만 때로는 으 rug하는 것들의 예가 없으면 답변이 완료되지 않습니다.

  • 육안으로 볼 수 있고 O (1) 대안이 존재하는 큰 N을 가진 데이터베이스에 O (N ^ 2) 개의 왕복 횟수와 같이 소개되기 전에 피할 수있는 병목 현상

또한 런타임 실행 속도와 관련이 없습니다.

  • 신중한 선제 디자인

  • 정적 타이핑 (!)

  • 등 / 모든 형태의 정신적 노력

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