조기 최적화는 실제로 모든 악의 근원입니까?


215

내 동료가 오늘이라는 클래스를 커밋했습니다.이 클래스는 ThreadLocalFormat기본적으로 Java 형식 클래스 인스턴스를 스레드 로컬로 이동했습니다. 스레드 안전하지 않고 "상대적으로 비싸지 않기"때문입니다. 나는 빠른 테스트를 작성하고 초당 200,000 개의 인스턴스를 생성 할 수 있다고 계산했으며, 그가 그 수를 많이 만들 었는지 물었다. 그는 훌륭한 프로그래머이며 팀의 모든 사람은 매우 숙련되어 결과 코드를 이해하는 데 아무런 문제가 없지만 실제 필요가없는 곳을 최적화하는 경우였습니다. 그는 내 요청에 따라 코드를 백업했습니다. 어떻게 생각해? 이것이 "조기 최적화"의 경우이며 실제로 얼마나 나쁩니 까?


23
조기 최적화와 불필요한 최적화를 구별해야한다고 생각합니다. 나에게 '미숙 한 가치를 추가하지는 않는다'는 말이 있지만 '생애주기가 너무 이른'것을 제안합니다. 늦은 최적화에 대한 요구 사항 인 IMO는 복잡한 디자인을 의미합니다.

110
그렇습니다. 그러나 악은 다항식이며 많은 뿌리를 가지고 있으며, 그중 일부는 복잡합니다.
dan_waterworth 12

7
Knuth가 1974 년에이 글을 썼다는 점을 고려해야합니다. 70 년대에는 현재 느린 프로그램을 작성하는 것이 쉽지 않았습니다. 그는 파스칼을 염두에두고 Java 나 PHP를 쓰지 않았다.
13:51에 ceving

4
아닙니다. 모든 악의 근원은 탐욕입니다.
Tulains Córdova

12
@ceving 70에서 느린 프로그램을 작성하는 것은 오늘날처럼 쉬웠습니다. 잘못된 알고리즘이나 잘못된 데이터 구조를 선택하면 BAM! 모든 곳에서 성능이 저하됩니다. 다른 방법으로 논쟁 할 수 있습니다. 오늘날이 도구는 훨씬 더 많은 도구이며 프로그래머가 여전히 가장 기본적인 저장 작업을 수행하는 소프트웨어를 작성한다는 점에서 변명 할 수 없어야합니다. 병행 성은 거의 상품이되었고 여전히 고통 받고 있습니다. 언어 나 도구, CPU 또는 메모리에서 성능 저하를 탓할 수 없습니다. 너무 많은 것들의 섬세한 균형이기 때문에 초기 최적화가 거의 불가능합니다.
Alex

답변:


322

전체 인용문을 명심해야합니다.

우리는 시간의 97 % 정도라는 작은 효율성을 잊어야합니다. 조기 최적화는 모든 악의 근원입니다. 그러나 우리는이 중요한 3 %의 기회를 포기해서는 안됩니다.

이것이 의미하는 것은 측정 된 성능 문제가없는 경우 성능 향상을 얻을 것이라고 생각 하기 때문에 최적화하지 않아야한다는 것입니다. 엄격한 루프 내에서 문자열 연결을 수행하지 않는 것과 같은 명백한 최적화가 있지만, 명확하게 최적화되지 않은 것은 측정 할 수있을 때까지 피해야합니다.

"조기 최적화"의 가장 큰 문제점은 예기치 않은 버그가 발생할 수 있으며 시간 낭비가 크다는 것입니다.


7
도널드 크 누스 출신이기 때문에 그가 그것을 뒷받침할만한 증거가 있다면 나는 놀라지 않을 것입니다. BTW, Src : Statements, ACM Journal Computing Surveys, Vol 6, No. 4, 1974 년 12 월의 구조화 된 프로그래밍 p.268. citeseerx.ist.psu.edu/viewdoc/…
mctylr

28
... 좋은 프로그래머는 그러한 추론으로 만족에 빠지지 않을 것이며, 중요한 코드를주의 깊게 살펴 보는 것이 현명 할 것입니다. 그러나 그 코드가 확인 된 후에 만 (
만약

21
오늘 20k의 rep 사용자에게 a HashSet대신에 사용하는 List것이 조기 최적화 되었다고 말합니다 . 해당 유스 케이스는 정적으로 초기화 된 콜렉션으로, 그 목적은 룩업 테이블 역할을하는 것이 었습니다. 나는 작업과 조기 최적화에 적합한 도구를 선택하는 데 차이점이 있다고 잘못 생각하지 않습니다. 나는 당신의 게시물 이이 철학을 확인한다고 생각합니다 : There are obvious optimizations...anything that isn't trivially clear optimization should be avoided until it can be measured.HashSet의 최적화가 철저하게 측정되고 문서화되었습니다.
분쇄

9
@crush : yes : Set보다 의미 적으로 정확하고 유익 List하기 때문에 최적화 측면 이상의 것이 있습니다.
Erik Allik

7
조기 최적화가 전체 애플리케이션 아키텍처를 설계하여 일반적으로 빠르게 실행하고 확장하며 쉽게 최적화 할 수 있도록 설계하는 것과 혼동해서는 안된다고 덧붙이고 싶습니다.
Erik Allik

111

마이크로 최적화는 컨텍스트를 없애기 때문에 조기 마이크로 최적화는 모든 악의 근원입니다. 그들은 거의 예상대로 행동하지 않습니다.

중요한 순서대로 좋은 초기 최적화는 무엇입니까?

  • 아키텍처 최적화 (응용 프로그램 구조, 구성 및 계층화 방식)
  • 데이터 흐름 최적화 (애플리케이션 내부 및 외부)

일부 중간 개발주기 최적화 :

  • 데이터 구조, 성능 향상 또는 필요한 경우 오버 헤드가 낮은 새로운 데이터 구조 도입
  • 알고리즘

일부 최종 개발주기 최적화

  • 코드 핫팟 찾기 (단단한 루프, 최적화되어야 함)
  • 코드의 계산 부분에 대한 프로파일 링 기반 최적화
  • 응용 분야에서 마이크로 최적화를 수행 할 수 있으며 그 영향을 정확하게 측정 할 수 있습니다.

모든 조기 최적화 악마입니다 개발 라이프 사이클의 잘못된 시간에하는 경우에 마이크로 최적화 악 에 부정적인 아키텍처에 영향을 미칠 수있는 부정적인 초기 생산성에 영향을 미칠 수있는 현명한 관련이없는 성능이 될 수 또는 마지막에 해로운 영향을, 다른 환경 조건으로 인한 개발.

퍼포먼스가 중요하다면 (항상 그래야만한다) 항상 크게 생각하십시오 . 성능은 더 큰 그림이며 다음과 같은 것이 아닙니다 . int 또는 long을 사용해야 합니까? 상향식 대신 성능으로 작업 할 때는 하향식으로 이동하십시오 .


"최적화 : 귀하의 최악의 적", 조셉 M. 신인의 : flounder.com/optimization.htm
론 루블

53

첫 번째 측정없는 최적화 는 거의 항상 조기입니다.

나는 이것이 사실이며 일반적인 경우에도 마찬가지라고 생각합니다.


여기 여기! 고려되지 않은 최적화는 코드를 유지 관리 할 수 ​​없게 만들고 종종 성능 문제의 원인입니다. 예를 들어, 프로그램이 성능에 도움이 될 수 있다고 생각하기 때문에 멀티 스레드 프로그램이지만 실제 솔루션은 구현하기에는 너무 복잡한 여러 프로세스 일 것입니다.
제임스 앤더슨

문서화되어 있지 않다면.
nawfal

예. 전적으로 동의합니다. 먼저 측정해야합니다. 무언가를 끝까지 테스트하고 각 단계를 측정 할 때까지 병목 현상의 위치를 ​​알 수있는 방법이 없습니다.
Oliver Watkins

측정이 가능합니다. 나는 노련한 전문가가 흔적을 읽고 프로파일을 실행하여 더 이상 얻을 것이 없다고 생각하는 벽을 치는 데 몇 주를 소비하는 것을 보았습니다. 그런 다음 코드 전체를 읽고 몇 시간 만에 10 배 개선을 위해 전체적으로 몇 가지 사항을 변경했습니다. 전체 코드가 제대로 설계되지 않았기 때문에 프로필에 핫 경로가 표시되지 않았습니다. 또한 프로파일 러는 핫 패스를 요구하지 않는 것으로 나타났습니다. "측정"하는 사람은 핫 패스를 최적화했을 것이지만, 핫 패스는 다른 불량 코드의 증상이라는 것을 깨달아야합니다.
Bengie

42

다음과 같은 경우 최적화가 "악"입니다.

  • 덜 명확한 코드
  • 훨씬 더 많은 코드
  • 덜 안전한 코드
  • 프로그래머 시간 낭비

귀하의 경우에는 약간의 프로그래머 시간이 이미 소요 된 것처럼 보이며 코드가 너무 복잡하지 않았습니다 (팀의 모든 사람이 이해할 수 있다고 귀하의 의견에서 추측) 및 코드는 조금 더 미래 증거입니다 ( 스레드 안전, 지금 귀하의 설명을 이해 한 경우). 조금 사악한 것 같습니다. :)


4
글 머리 기호의 관점에서 비용이 전달 된 상각액보다 큰 경우에만 가능합니다. 복잡성으로 인해 가치가 발생하는 경우가 많으며 이러한 경우 기준을 충족하도록 가치를 캡슐화 할 수 있습니다. 또한 재사용되고 더 많은 가치를 제공합니다.

1
그 첫 두 포인트는 나에게 주요 포인트이며, 네 번째 포인트는 조기 최적화를 수행하는 부정적인 결과입니다. 특히 표준 라이브러리에서 누군가 기능을 다시 구현하는 것을 볼 때마다 붉은 깃발입니다. 마찬가지로, 나는 내장 명령이 너무 느리다는 것을 염려했기 때문에 누군가가 문자열 조작을위한 사용자 정의 루틴을 구현하는 것을 보았습니다.
jhocking 12

8
코드 스레드를 안전하게 만드는 것은 최적화가 아닙니다.
mattnz

38

나는이 질문이 5 살이라는 사실에 놀랐지 만, 아무도 Knuth가 말한 것보다 더 많은 문장을 게시 한 적이 없다. 유명한 인용문을 둘러싼 몇 개의 문단이 그것을 잘 설명해줍니다. 인용되는이 논문은 " 구문을 통한 구조화 된 프로그래밍 "이라고하며 , 거의 40 년이되었지만 더 이상 존재하지 않는 논쟁과 소프트웨어 운동에 관한 것입니다. 놀랍게도 많은 양의 말이 여전히 적용됩니다.

다음은 더 큰 인용문입니다 (pdf의 8 페이지, 원본 268 페이지).

예 2에서 예 2a 로의 속도 개선은 약 12 ​​%에 불과하며 많은 사람들이 그 의미를 무시할 것입니다. 오늘날 많은 소프트웨어 엔지니어들이 공유하는 기존의 지혜는 소규모의 효율성을 무시할 것을 요구합니다. 그러나 나는 이것이 "최적화 된"프로그램을 디버깅하거나 유지할 수없는 페니와 어리석은 어리석은 프로그래머에 의해 실행되는 학대에 대한 과잉 반응이라고 생각합니다. 기존의 엔지니어링 분야에서 쉽게 얻을 수있는 12 % 개선은 결코 한계로 간주되지 않습니다. 소프트웨어 엔지니어링에서도 동일한 관점이 우선해야한다고 생각합니다. 물론 일회성 작업에서 이러한 최적화를 수행하는 것을 귀찮게하지는 않지만 양질의 프로그램을 준비해야 할 때 그러한 효율성을 거부하는 도구로 자신을 제한하고 싶지 않습니다.

효율성의 성패가 학대를 초래한다는 것은 의심의 여지가 없습니다. 프로그래머는 프로그램의 중요하지 않은 부분의 속도에 대해 생각하거나 걱정하는 데 많은 시간을 낭비하며, 이러한 효율성 시도는 실제로 디버깅 및 유지 관리를 고려할 때 큰 부정적인 영향을 미칩니다. 우리 시간의 97 % 정도라는 작은 효율성을 잊어야합니다. 조기 최적화는 모든 악의 근원입니다.

그러나 우리는이 중요한 3 %의 기회를 포기해서는 안됩니다. 훌륭한 프로그래머는 그러한 추론을 통해 만족에 빠지지 않을 것이며, 중요한 코드를주의 깊게 살펴 보는 것이 현명 할 것입니다. 코드가 확인 된 후에 만 ​​가능합니다. 측정 도구를 사용하는 프로그래머의 보편적 경험은 직관적 인 추측이 실패하기 때문에 프로그램의 어떤 부분이 실제로 중요한지를 미리 판단하는 것은 종종 실수입니다.

이전 페이지의 또 다른 좋은 점 :

시대의 추세에 따라 지난 10 년간 내 자신의 프로그래밍 스타일이 바뀌었다 (예 : 더 이상 까다 롭지 않고 갈 줄임). 내 스타일의 주요한 변화는 이 내부 루프 현상에. 이제 중요한 내부 루프의 모든 작업에서 매우 황달 한 눈으로보고 일부 프로그램을 제거 할 수 있도록 프로그램 및 데이터 구조를 수정하려고합니다 (예 1에서 예 2로 변경). 이 접근법의 이유는 다음과 같습니다. a) 내부 루프가 짧기 때문에 오래 걸리지 않습니다. b) 그 대가는 실제적이다. 그리고 c) 그런 다음 내 프로그램의 다른 부분에서 효율성이 떨어 지므로 읽을 수 있고 더 쉽게 작성하고 디버깅 할 수 있습니다.


20

성능이 측정되지는 않았지만 코드 크기를 늘리거나 가독성을 떨어 뜨리지 않고 훨씬 더 빠르게 만들 수있는 명백한 나쁜 코드 나 코드를 정당화하기 위해이 인용구를 사용하는 경우가 종종있었습니다.

일반적으로 초기의 미세 최적화는 나쁜 생각 일 수 있습니다. 그러나 매크로 최적화 (O (N ^ 2) 대신 O (log N) 알고리즘을 선택하는 것과 같은 것)는 종종 가치가 있으며 O (N ^ 2) 알고리즘을 작성하는 것은 낭비가 될 수 있으므로 조기에 수행해야합니다. 그런 다음 O (log N) 접근 방식을 위해 완전히 버립니다.

단어가 참고 가 될 수 있습니다 다음 O (N ^ 2) 알고리즘이 간단하고 쓰기 쉬운 경우가 너무 느린 것으로 밝혀지면, 당신은 많은 죄책감없이 나중에 버릴 수 있습니다. 그러나 두 알고리즘이 비슷하게 복잡하거나 예상 작업 부하가 너무 커서 이미 더 빠른 알고리즘이 필요하다는 것을 알고 있다면 조기에 최적화하는 것이 장기적으로 총 작업 부하를 줄이는 건전한 엔지니어링 결정입니다.

따라서 일반적으로 올바른 접근 방식은 코드 작성을 시작하기 전에 옵션이 무엇인지 확인하고 상황에 가장 적합한 알고리즘을 의식적으로 선택하는 것입니다. 가장 중요한 것은 "조기 최적화는 모든 악의 근원"이라는 문구가 무지에 대한 변명이 아니라는 것입니다. 커리어 개발자는 일반적인 운영 비용이 얼마인지에 대한 일반적인 아이디어를 가지고 있어야합니다. 예를 들어

  • 그 문자열은 숫자보다 더 비싸다
  • 동적 언어는 정적으로 유형이 지정된 언어보다 훨씬 느립니다.
  • 연결된 목록에 비해 배열 / 벡터 목록의 장점
  • 해시 테이블 사용시기, 정렬 된 맵 사용시기 및 힙 사용시기
  • "이중 장치와 함께 작동하는 경우" "double"과 "int"는 데스크톱에서 유사한 성능을 갖지만 (FP는 더 빠를 수도 있음) FPU가없는 저가형 휴대 장치에서는 "double"이 100 배 느려질 수 있습니다.
  • 인터넷을 통한 데이터 전송은 HDD 액세스보다 느리고 HDD는 RAM보다 훨씬 느리며 RAM은 L1 캐시 및 레지스터보다 훨씬 느리며 인터넷 작업은 무기한 차단 될 수 있습니다 (언제든지 실패 할 수 있음).

또한 개발자는 작업에 적합한 도구를 쉽게 사용할 수 있도록 데이터 구조 및 알고리즘 도구 상자에 익숙해야합니다.

많은 지식과 개인용 도구 상자가 있으면 거의 쉽게 최적화 할 수 있습니다. 불필요한 최적화에 많은 노력을 기울이는 것은 사악한 일입니다 (그리고 그 함정에 두 번 이상 넘어가는 것을 인정합니다). 그러나 배열 대신 세트 / 해시 테이블을 선택하거나 string [] 대신 double [] 에 숫자 목록을 저장하는 것만 큼 최적화가 쉬운 경우 왜 그렇지 않습니까? 나는 여기 Knuth에 동의하지 않을 수도 있습니다. 확실하지 않지만, 나는 그가 저수준 최적화에 대해 이야기하고 있다고 생각하지만 고수준 최적화에 대해서는 이야기하고 있습니다.

1974 년 컴퓨터는 느리고 컴퓨팅 성능이 비싸서 일부 개발자는 한 줄씩 지나치게 최적화하는 경향이있었습니다. 나는 그것이 Knuth가 추진 한 것이라고 생각합니다. 그는 1974 년에 말 그대로 미친 이야기 일 것이기 때문에 "성능에 대해 전혀 걱정하지 마십시오"라고 말하지 않았습니다. Knuth는 최적화 방법 을 설명 하고 있었습니다 . 간단히 말해 병목 현상에만 집중해야하며 그 전에 병목 현상을 찾기 위해 측정을 수행해야합니다.

측정 할 프로그램을 작성할 때까지 병목 현상을 찾을 수 없으므로 측정 할 항목이 있기 전에 성능 결정을 내려야 합니다 . 때로는 이러한 결정이 잘못되면 변경하기가 어렵습니다. 이러한 이유로, 어떤 비용이 드는지에 대한 일반적인 아이디어를 가지고 있으면 사용 가능한 하드 데이터가 없을 때 합리적인 결정을 내릴 수 있습니다.

작업을 최적화하는 데 걸리는 시간과 성능에 대해 얼마나 걱정해야합니까? 몇 번만 실행되는 스크립트를 작성할 때 성능에 대한 걱정은 대개 완전한 시간 낭비입니다. 그러나 Microsoft 또는 Oracle에서 일하고 수천 명의 다른 개발자 가 수천 가지 다른 방식으로 사용할 라이브러리에서 작업하는 경우 지옥을 최적화하는 데 비용을 지불하여 다양한 모든 것을 처리 할 수 ​​있습니다 사용 사례를 효율적으로 그럼에도 불구하고 성능에 대한 요구는 항상 가독성, 유지 보수성, 우아함, 확장 성 등에 대한 요구와 균형을 이루어야합니다.


2
아멘. 요즘에는 잘못된 도구를 사용하여 정당화하려는 사람들이 조기 최적화를 너무 자유롭게 수행합니다. 작업에 적합한 도구를 미리 알고 있다면 사용하지 않을 이유가 없습니다.
분쇄

13

개인적으로 이전 스레드 에서 다룬 것처럼 성능 문제가 발생할 것으로 예상되는 상황에서는 초기 최적화가 나쁘지 않다고 생각합니다. 예를 들어, 나는 표면 모델링 및 분석 소프트웨어를 작성하는데, 여기서 정기적으로 수천만 개의 개체를 처리합니다. 설계 단계에서 최적의 성능을 계획하는 것은 취약한 설계의 늦은 최적화보다 훨씬 뛰어납니다.

고려해야 할 또 다른 사항은 향후 애플리케이션 확장 방법입니다. 코드 수명이 길다고 생각한다면 디자인 단계에서 성능을 최적화하는 것도 좋습니다.

내 경험상 늦게 최적화하면 높은 가격으로 빈약 한 보상을 제공합니다. 알고리즘 선택 및 조정을 통해 설계 단계에서 최적화하는 것이 훨씬 좋습니다. 코드 작동 방식을 이해하기 위해 프로파일 러에 따라 고성능 코드를 얻는 것은 좋은 방법이 아니므로이를 미리 알아야합니다.


이것은 확실히 맞습니다. 조기 최적화는 지역적 영향 (디자인이 글로벌 영향을 미침)만의 방식으로 불명확 한 이점을 위해 코드를 이해하기 어렵거나 이해하기 어려울 때입니다.
Paul de Vrieze

2
그것은 정의에 관한 것입니다. 최적의 방식으로 수행하기 위해 코드를 디자인하고 작성하는 데 최적화를 사용합니다. 대부분의 경우 코드가 빠르거나 효율적이지 않다는 것을 알게되면 코드를 해킹하는 것으로 간주합니다. 나는 일반적으로 디자인하는 동안 많은 시간을 최적화하는 데 소비합니다.

3
처음에는 디자인을 최적화하고 마지막에는 코드를 최적화하십시오.
BCS

대부분의 프로그래머에게는 성능 문제가 발생할 것이라고 생각하지만 실제로는 그렇지 않습니다. 많은 사람들이 1000 개의 엔티티를 처리 할 때 성능에 대해 걱정합니다. 데이터에 대한 기본 테스트에서 1000000 개의 엔티티에 도달 할 때까지 성능이 양호 함을 보여줍니다.
Toby Allen

1
"디자인 단계에서 최적의 성능을위한 계획은 약한 디자인의 늦은 최적화보다 훨씬 우수합니다." "늦은 최적화는 높은 가격으로 빈약 한 보상을 제공합니다." 아마도 생산 된 모든 시스템의 97 %에는 해당되지 않지만 많은 시스템이 당연히 많은 시스템에 해당됩니다.
Olof Forshell

10

사실 나는 조기 비 최적화가 모든 악의 근원이라는 것을 배웠다.

사람들이 소프트웨어를 작성할 때 처음에는 불안정성, 기능 제한, 사용 편의성 및 성능 저하와 같은 문제가 있습니다. 소프트웨어가 성숙 할 때 이러한 모든 사항은 일반적으로 수정됩니다.

성능을 제외한 모든 것. 아무도 성능에 관심이없는 것 같습니다. 그 이유는 간단합니다. 소프트웨어가 충돌하면 누군가 버그를 수정하게되며, 그로 인해 기능이 누락되거나 누군가가이를 구현하고 수행 할 수 있습니다. 소프트웨어의 성능이 좋지 않은 경우 마이크로 최적화가 없어서가 아니라 많은 경우에 발생합니다. 나쁜 디자인 때문에 아무도 소프트웨어의 디자인을 건드리지 않을 것입니다. 이제까지.

보쉬를보십시오. 지옥만큼 느립니다. 더 빨라질까요? 어쩌면 몇 퍼센트 정도만있을 수도 있습니다. VMWare, VBox 또는 QEMU와 같은 가상화 소프트웨어에 필적 할만한 성능을 얻지 못할 것입니다. 설계 상 느리기 때문에!

소프트웨어의 문제가 느리다는 것은 매우 느리기 때문에 성능을 여러 가지로 향상 시켜서 만 해결할 수 있습니다. + 10 %는 단순히 느린 소프트웨어를 만들지 않습니다. 그리고 나중에 최적화하여 일반적으로 10 %를 초과하지 않습니다.

따라서 소프트웨어에서 성능이 중요한 경우, 설계시 "아, 속도가 느리지 만 나중에 개선 할 수 있습니다"라는 생각 대신 처음부터이를 고려해야합니다. 당신이 할 수 없기 때문에!

나는 그것이 당신의 특정한 경우에 맞지 않는다는 것을 알고 있습니다. 그러나 그것은 "초기 최적화가 정말로 모든 악의 근원입니까?"라는 일반적인 질문에 대답합니다. -명확한 NO.

모든 기능과 같은 모든 최적화는 신중하게 설계되고 신중하게 구현되어야합니다. 그리고 여기에는 비용과 이익에 대한 적절한 평가가 포함됩니다. 측정 가능한 성능 향상을 생성하지 않는 경우 몇 사이클을 절약하기 위해 알고리즘을 최적화하지 마십시오.

예를 들어, 함수를 인라인하여 함수의 성능을 향상시킬 수 있으며, 수 많은 사이클을 절약 할 수 있지만 동시에 실행 파일의 크기를 늘려 TLB 및 캐시의 기회가 증가하여 수천 사이클 또는 페이징 작업은 성능을 완전히 저하시킵니다. 이러한 것들을 이해하지 못하면 "최적화"가 나빠질 수 있습니다.

멍청한 최적화는 "조기"최적화보다 더 나쁘지만, 둘 다 여전히 조기 비 최적화보다 낫습니다.


6

PO에는 두 가지 문제가 있습니다. 첫째, 비 필수 작업에 사용되는 개발 시간으로, 더 많은 기능을 작성하거나 더 많은 버그를 수정하는 데 사용될 수 있으며, 둘째, 코드가 효율적으로 실행되고 있다는 잘못된 보안 감각이 있습니다. PO는 종종 병목 현상이되지 않는 코드를 최적화하면서 코드를 알아 차리지 못합니다. "조기"비트는 적절한 측정을 사용하여 문제가 식별되기 전에 최적화가 수행됨을 의미합니다.

기본적으로 그렇습니다. 이것은 조기 최적화처럼 들리지만 버그가 발생하지 않는 한 반드시 되돌릴 필요는 없습니다. 결국 최적화되었습니다! (!)


"더 많은 기능 작성"대신 "더 많은 테스트 작성"이라고 말하는 것입니까? :)
Greg Hewgill

1
더 많은 기능이 더 많은 테스트 :) 수반
workmad3

어, 그래! 그것이 바로 제가 의미 한
바입니다

2
이 코드는 더 복잡해지며 보편적으로 사용되지 않을 것입니다. 그것을 백업하고 비슷한 것들을 코드를 깨끗하게 유지합니다.
Paul de Vrieze

3

나는 그것이 Mike Cohn이 코드를 '골드 도금'이라고 부르는 것이라고 믿고 있습니다.

그는 그것에 대해 충고했다.

PS '골드 도금'은 종별 기능의 종별 기능 일 수 있습니다. 코드를 볼 때 불필요한 최적화, '미래 방지'클래스 등의 형태를 취합니다.


2
"골드 도금"은 최적화와 다릅니다. "골드 도금"은 일반적으로 제품에 중요하지 않지만 시원하게 보이고 느껴지는 "벨과 휘파람"(추가 기능)을 추가하는 것입니다.
Scott Dorman

3

코드를 이해하는 데 아무런 문제가 없으므로이 경우는 예외로 간주 될 수 있습니다.

그러나 일반적으로 최적화는 코드를 이해하기 어렵고 이해하기 어렵 기 때문에 필요한 경우에만 적용해야합니다. 간단한 예-몇 개의 요소 만 정렬해야한다는 것을 알고 있다면 BubbleSort를 사용하십시오. 그러나 요소가 증가 할 수 있다고 생각하고 얼마를 알지 못한다면 QuickSort (예 :)로 최적화하는 것은 악한 것이 아니라 필수입니다. 그리고 이것은 프로그램을 설계 할 때 고려해야합니다.


1
동의하지 않습니다. 버블 정렬을 사용하지 말라고 말하고 싶습니다. Quicksort는 사실상의 표준이되었으며 잘 이해되며 모든 시나리오에서 기포 정렬만큼 쉽게 구현할 수 있습니다. ) 최소 공통 분모는 더이상 그 부족하지 않은

1
항목의 정말 작은 수의 경우, 퀵에 필요한 재귀가 아닌 거품 정렬이 빠른 퀵 (즉 정렬 된 목록을 quicksorting)의 최악의 시나리오에 있음을 언급 ... 그래도 괜찮은 거품 정렬 때보 다 느리게 만들 수 있습니다
workmad3

그래,하지만 서로 다른 요구에 대한 알고리즘을 선택하는 방법을 그냥 예입니다)

사실이지만 빠른 정렬을 기본 정렬로 사용합니다. bubblesort가 성능을 향상시킬 것이라고 생각한다면 이것은 다른 방법이 아닌 최적화 일 것입니다. 이해하기 쉽고 일반적으로 더 낫기 때문에 quicksort를 기본값으로 선택합니다.

2
기본 정렬에 대한 내 생각은 라이브러리가 제공하는 것 (qsort (), .sort (), (sort ...) 등)입니다.
David Thornley

3

조기 최적화 문제는 기존 코드를 더 빨리 다시 작성할 때 주로 발생한다는 것을 알았습니다. 처음에는 복잡한 최적화를 작성하는 것이 문제가 될 수있는 방법을 알 수 있지만, 대부분 조기 최적화가 고장난 것으로 알려진 것을 고치는 데 못생긴 머리를 키우는 것을 봅니다.

그리고 최악의 예는 누군가 표준 라이브러리에서 기능을 다시 구현하는 것을 볼 때마다입니다. 그것은 중요한 적기입니다. 마찬가지로, 나는 내장 명령이 너무 느리다는 것을 염려했기 때문에 누군가가 문자열 조작을위한 사용자 정의 루틴을 구현하는 것을 보았습니다.

이로 인해 코드를 이해하기 어렵고 (나쁜) 유용하지 않은 (나쁜) 작업에 많은 시간을 소비합니다.


3

다른 관점에서 볼 때, 대부분의 프로그래머 / 개발자는 성공을 계획하지 않으며 "시제품"은 거의 항상 릴리스 1.0이됩니다. 고급스럽고 섹시하며 기능성이 뛰어난 프론트 엔드 (기본적으로 UI)가 널리 채택 된 사용자 채택과 열의를 불러 일으킨 4 개의 개별 오리지널 제품을 직접 경험했습니다. 이러한 각 제품에서, 특히 더 크고 더 까다로운 고객이 제품을 채택하기 시작함에 따라 성능 문제가 비교적 짧은 시간 (1 ~ 2 년) 내에 발생하기 시작했습니다. 새로운 기능 개발이 경영진의 우선 순위 목록을 지배했지만 성능이 이슈 목록을 곧 장악했습니다. 각 릴리스에 새 기능이 추가되어 성능 문제로 인해 거의 액세스 할 수없는 새로운 기능이 추가됨에 따라 고객은 점점 더 실망했습니다.

따라서 "시제품 유형"에 거의 또는 전혀 관심이 없었던 매우 근본적인 설계 및 구현 결함은 제품 (및 회사)의 장기적인 성공에 큰 걸림돌이되었습니다.

고객 데모는 XML DOM, SQL Express 및 많은 클라이언트 측 캐시 데이터를 사용하여 랩탑에서 멋지게 보이고 성능을 발휘할 수 있습니다. 성공하면 프로덕션 시스템에서 화상을 입을 수 있습니다.

1976 년 우리는 여전히 제곱근을 계산하거나 큰 배열을 정렬하는 최적의 방법에 대해 토론하고 있었고 Don Knuth의 속임수는 문제 해결에 중점을 두지 않고 설계 프로세스 초기에 저수준 루틴을 최적화하는 데 집중하는 실수에 초점을 맞추 었습니다. 현지화 된 코드 영역을 최적화합니다.

효율적인 코드 (C ++, VB, T-SQL 등)를 작성하지 않거나 데이터 저장소를 제대로 설계하지 않았거나 네트워크 작업 아키텍처를 고려하지 않은 것에 대한 변명으로 격언을 반복 할 때 IMO는 단지 우리의 일의 본질에 대한 매우 얕은 이해. 레이


1
하하, 또는 3 명의 사용자가있는 데모가 1.0과 함께 1.0이 될 때.
Olof Forshell

1

"미숙 한"정의 방법에 따라 다릅니다. 글을 쓸 때 저수준 기능을 빠르게 만드는 것은 본질적으로 악한 것이 아닙니다. 나는 그것이 인용문에 대한 오해라고 생각합니다. 때로는 그 견적이 더 많은 자격과 관련이 있다고 생각합니다. 가독성에 대한 m_pGladiator의 의견을 반영합니다.


1

대답은 다음과 같습니다. 복잡한 데이터베이스 쿼리와 같은 특정 유형의 작업에는 효율성이 큰 문제라고 주장합니다. 다른 많은 경우에 컴퓨터는 사용자 입력을 기다리는 데 대부분의 시간을 소비하므로 대부분의 코드를 최적화하는 것은 최선의 노력 낭비이며 최악의 경우 비생산적입니다.

경우에 따라 효율성 또는 성능 (인식 또는 실제)을 고려하여 설계 할 수 있습니다. 적절한 알고리즘을 선택하거나 사용자 인터페이스를 설계하여 특정 비싼 작업이 백그라운드에서 발생하도록합니다. 많은 경우 핫스팟을 결정하기위한 프로파일 링 또는 기타 작업으로 10/90의 이점을 얻을 수 있습니다.

제가 설명 할 수있는 한 가지 예는 약 560 개의 테이블이있는 법원 사건 관리 시스템에서 한 번 한 데이터 모델입니다. 정규화되기 시작했고 (특정 big-5 회사의 컨설턴트가 '아름답게 정규화'했음) 비정규 화 된 데이터 항목을 4 개만 넣어야했습니다.

  • 검색 화면을 지원하는 하나의 구체화 된보기

  • 구체화 된 뷰로는 수행 할 수없는 다른 검색 화면을 지원하는 하나의 트리거 유지 보수 테이블.

  • 비정규 화 된보고 테이블 1 개 (데이터웨어 하우스 프로젝트가 준비 될 때 일부 처리량 보고서를 가져와야했기 때문에 존재했습니다)

  • 시스템 내에서 가장 많은 수의 개별 이벤트를 검색해야하는 인터페이스에 대한 하나의 트리거 유지 테이블.

이것은 (오스트랄리아에서 가장 큰 J2EE 프로젝트였으며 100 년이 넘는 개발자 시간이었습니다.) 데이터베이스 스키마에 4 개의 비정규 화 된 항목이 있었으며 그 중 하나는 실제로 거기에 속하지 않았습니다.


1

조기 최적화는 모든 악의 근원이 아닙니다. 그러나 단점이 있습니다.

  • 개발하는 동안 더 많은 시간을 투자
  • 당신은 그것을 테스트하는 데 더 많은 시간을 투자
  • 그렇지 않은 버그를 수정하는 데 더 많은 시간을 투자

조기 최적화 대신 조기 가시성 테스트를 수행하여 더 나은 최적화가 실제로 필요한지 확인할 수 있습니다.


1

"PMO"(부분 인용)를 고수하는 대부분의 사람들은 최적화가 측정을 기반으로해야하며 측정이 끝날 때까지 수행 할 수 없다고 말합니다.

또한 개발이 완료됨에 따라 성능 테스트가 마지막에 수행되는 것은 대규모 시스템 개발에서 얻은 경험이기도합니다.

우리가이 사람들의 "조언"을 따라야한다면 모든 시스템은 엄청나게 느릴 것입니다. 하드웨어 요구 사항이 원래 예상보다 훨씬 크기 때문에 비용도 많이 듭니다.

나는 개발 과정에서 정기적으로 성능 테스트를 옹호 해왔다. 새로운 코드의 존재 (이전에 존재하지 않았던 곳)와 기존 코드의 상태 둘 다를 나타낼 것이다.

  • 새로 구현 된 코드의 성능은 기존의 유사한 코드의 성능과 비교할 수 있습니다. 새로운 코드의 성능에 대한 "느낌"은 시간이 지남에 따라 확립 될 것입니다.
  • 기존 코드가 갑자기 엉망이되면 코드에 문제가 있음을 이해하고 나중에 전체 시스템에 영향을 줄 때가 아니라 즉시 조사 할 수 있습니다.

또 다른 애완 동물 아이디어는 기능 블록 수준에서 소프트웨어를 계측하는 것입니다. 시스템이 실행됨에 따라 기능 블록의 실행 시간에 대한 정보를 수집합니다. 시스템 업그레이드가 수행되면 이전 릴리스에서 수행했던 기능 블록과 성능이 저하 된 기능 블록을 확인할 수 있습니다. 소프트웨어 화면에서 성능 데이터는 도움말 메뉴에서 액세스 할 수 있습니다.

PMO가 의미하거나 의미하지 않는 것에 대한 훌륭한 부분을 확인하십시오 .

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