너무 일찍 최적화하는 것이 왜 그렇게 나쁜가?


168

최적화를 조금 살펴본 후, 나는 게임을 너무 일찍 최적화하는 것이 보편적으로 인정되는 죄인 것으로 판명되었습니다.

나는 이것을 정말로 이해하지 못한다. 성능을 염두에두고 처음으로 개발하는 것이 아니라 결국 게임의 핵심 구조 중 일부를 변경하는 것이 매우 어렵지 않을까요?

게임이 끝날 때까지 기다리면 최적화가 필요한지 알 수 있지만 어쨌든하지 않아야합니다. 결국 게임을 실행할 수있는 다양한 장치를 넓힐 수 있으므로 잠재적 인 수가 증가합니다. 선수.

누군가 너무 일찍 최적화하는 것이 왜 그렇게 나쁜 아이디어인지 설명해 줄 수 있습니까?


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Josh

3
"시간 낭비"라는 대답을하기가 쉽지 않았습니다. "쇼핑 할 때 왜 돈을 저축하려고합니까?"
Fattie

27
반대로 많은 엔지니어들은 "너무 빨리 최적화하지 마십시오"라는 문장은 단순히 잘못되었다고 말합니다 . 문장은 단순히 "최적화 대상을 알 때까지 최적화하지 마십시오"여야합니다. 아주 간단히 말해서, 시스템 A, B 및 C가 3 개인 경우 A가 병목 현상이 전혀없고 C가 실제로 병목 현상 인 경우에는 A를 전혀 무의미하게 최적화하는 것입니다. 이 예에서 분명히 A를 최적화하는 것은 시간 낭비였습니다. 따라서 BC 주 A, BC 중 어느 것이 최적화해야 할지를 알 때까지 최적화하지 마십시오 . 이것이 의미하는 전부입니다. 간단합니다.
Fattie

2
개발 중 응용 프로그램의 시간 클래스를 최적화하는 것은 일반적으로 일정한 시간 인 루프에서 몇 가지 명령을 제거하는 것과는 매우 다릅니다. "for 루프를 이런 식으로 작성하면 하나의 CPU 명령이 절약됩니다"대신 O (n) 대 O (n log n)에 중점을 둡니다.

1
@phyrfox 사실,로드 시간을 줄이는 것이 나에게 더 인상적입니다. 3 초의로드 시간이 눈에.니다. 55fps ~ 60fps가 눈에 띄는 지 확실하지 않습니다.
immibis

답변:


237

전문:

의견에 대해 몇 가지 반대 의견이 제기되었으며, 우리가 "조기 최적화"라고 할 때 우리가 의미하는 바에 대한 오해에서 비롯된 것이라고 생각합니다. 따라서 이에 대해 약간의 설명을 추가하고 싶었습니다.

"조기 최적화하지 말아라"는 의미 는 아닙니다. "누가 아는 코드 작성이 잘못되었습니다. Knuth는 끝까지 정리할 수 없다고 말합니다"

"프로그램의 어떤 부분이 실제로 더 빨리 도움이 필요한지 알 때까지 최적화를 위해 시간과 가독성을 희생하지 마십시오." 일반적인 프로그램은 대부분의 시간을 몇 병목에 소비하므로 "모든 것"을 최적화하는 데 투자하면 병목 코드에 동일한 투자를 집중시키는 것과 같은 속도 향상을 얻지 못할 수 있습니다.

이는 의심스러운 경우 다음을 수행해야 함을 의미 합니다.

  • 작성하기 쉽고 이해하기 쉽고 수정하기 쉬운 코드를 선호

  • 추가 최적화가 필요한지 확인하십시오 (일반적으로 실행중인 프로그램을 프로파일 링하여 아래의 한 주석이 수학적 분석을 수행하는 메모에 유의하십시오-수학이 올바른지 확인 해야하는 유일한 위험)

조기 최적화는 아닙니다 :

  • 고려 된 방식으로 적절한 모듈 / 책임 / 인터페이스 / 통신 시스템을 선택하여 필요에 따라 확장 할 수있는 방식으로 코드를 구성하기위한 아키텍처 결정.

  • 시간이 오래 걸리거나 코드를 읽기 어렵게 만드는 간단한 효율성. 강력한 타이핑을 사용하는 것과 같은 일이 효율적이고 의도를 더 명확하게 만들 수 있습니다. 참조를 반복적으로 검색하는 대신 참조를 캐싱하는 것이 또 다른 예입니다 (케이스가 복잡한 캐시 무효화 로직을 요구하지 않는 한 간단한 방법을 먼저 프로파일 링 할 때까지 작성하지 않을 수도 있음).

  • 작업에 적합한 알고리즘 사용 A *는 경로 찾기 그래프를 철저히 검색하는 것보다 더 최적이고 복잡합니다. 또한 산업 표준이기도합니다. 테마를 반복하고 이와 같은 시도되고 진정한 방법을 고수하면 실제로는 단순한 모범 사례를 수행하는 것보다 코드를 이해하기가 쉽습니다. 이전 프로젝트에서 한 가지 방법으로 게임 기능 X를 구현하는 병목 현상이 발생한 경험이 있다면이 프로젝트에서 동일한 병목 현상을 다시 적용하여 실제 상황을 알 필요가 없습니다. 과거에 효과가 있었던 솔루션을 재사용 할 수 있고 재사용해야합니다. 계략.

이러한 모든 유형의 최적화는 잘 정당화되며 일반적으로 "미숙 한"레이블이 지정되지 않습니다 (8x8 체스 판 맵에 대한 최첨단 경로 찾기를 구현하는 토끼 구멍을 밟지 않는 한 ...)

이제 우리는이 정책이 게임에서 특히 유용한 이유에 대해 다음 과 같이 정리했습니다 .


gamedev에서 특히 반복 속도는 가장 소중한 것입니다. 우리는 종종 "재미를 찾기 위해"완성 된 게임과 함께 제공되는 것보다 훨씬 더 많은 아이디어를 구현하고 다시 구현할 것입니다.

정비공을 간단하고 약간 순진한 방식으로 프로토 타입하고 다음 날 재생 테스트를 할 수 있다면 가장 최적의 버전을 먼저 만드는 데 일주일을 보낸 것보다 훨씬 나은 위치에 있습니다. 특히 그것이 빨라지고 그 기능을 포기하게되면. 초기 테스트를 위해 간단한 방법을 사용하면 유지하지 않는 코드를 최적화하는 많은 낭비되는 작업을 줄일 수 있습니다.

최적화되지 않은 코드는 일반적으로 하나의 정확한 일을 최적으로 수행하도록 미세 조정 된 코드보다 수정하고 다른 변형을 시도하는 것이 일반적으로 더 쉽습니다. 이는 코드를 깨거나 버그를 도입하거나 속도를 늦추지 않고 취성 및 수정이 어려운 경향이 있습니다. 따라서 코드를 단순하고 변경하기 쉬운 상태로 유지하는 것은 대부분의 개발 (일반적으로 대상 사양 이상의 시스템에서 개발하므로 오버 헤드를 흡수하고 대상 경험을 먼저 얻는 데 집중할 수 있음)에서 약간의 런타임 비효율 성인 경우가 많습니다. 우리는 기능에서 필요한 것을 잠그고 현재 알고있는 부품을 느리게 최적화 할 수 있습니다.

예, 개발 후반에 프로젝트의 일부를 리팩토링하여 느린 지점을 최적화하는 것은 어려울 수 있습니다. 그러나 지난 달에 한 최적화는 그 이후로 게임이 발전한 방향과 호환되지 않거나 더 많은 기능과 내용을 얻은 후에 실제 병목 현상이 아닌 것으로 판명 된 것을 수정했기 때문에 개발 전체에서 반복적으로 리팩토링하고 있습니다. 에서.

게임은 이상하고 실험적입니다. 게임 프로젝트와 기술 요구가 어떻게 발전하고 성능이 가장 까다로운 곳을 예측하기는 어렵습니다. 실제로, 우리는 종종 잘못된 것들에 대해 걱정하게됩니다. 여기에서 성능 관련 질문을 검색하면 전혀 문제가되지 않을 것 같은 종이에있는 물건에주의를 기울이는 개발자들의 공통된 주제가 나타납니다.

극적인 예를 들자면 : 게임이 GPU에 한정된 경우 (드문 일이 아닌 경우) CPU 작업을 하이퍼 최적화하고 스레딩하는 데 소요되는 모든 시간에 실질적인 이점이 없을 수 있습니다. 더 나은 플레이어 경험을 위해 게임 개발 기능을 구현하고 연마하는 데 소요되는 모든 개발 시간이있었습니다.

전반적으로 게임 작업에 소비하는 대부분의 시간은 병목 현상이 발생하는 코드에 사용되지 않습니다. 특히 기존 엔진에서 작업 할 때 렌더링 및 물리 시스템의 초고가 내부 루프 요소는 대부분 손에 닿지 않습니다. 이 시점에서 게임 플레이 스크립트의 임무는 기본적으로 엔진을 벗어나지 않는 것입니다. 렌치를 넣지 않는 한 첫 번째 빌드에서는 아마 괜찮을 것입니다.

따라서 약간의 코드 위생 및 예산과는 별도로 (예 : 쉽게 재사용 할 수있는 경우 반복적으로 검색하거나 구성하지 말고, 길 찾기 / 물리 쿼리 또는 GPU 리드 백을 적당히 유지하는 등) 습관을 들이지 마십시오. 실제 문제가 어디에서 생산성을 향상시키는 지 알기 전에 최적화-잘못된 것을 최적화하는 데 시간을 낭비하지 않고 코드를 더 간단하고 쉽게 조정할 수 있습니다.


38
여기서는 코드의 가독성과 선명도의 중요성과 코드를 조기에 최적화하여 코드를 이해하기 어렵고 버그를 도입하기 쉽게 만드는 위험을 강조하는 StackOverflow에 대한 추가 논의가 있습니다.
DMGregory

8
좋은 답변은 " 최종 성능을 염두에두고 처음 개발하는 것이 아니라 결국 게임의 일부 핵심 구조를 변경하는 것이 매우 어렵지 않습니까? " 물론 처음부터 효율성을 위해 디자인하려고합니다. 두 가지 선택 사항이 제시되면보다 효율적인 선택 사항을 선택하십시오. 실패하면, 잘 정의 된 인터페이스로 가능한 한 모듈 식으로 게임을 작성하십시오. 그런 다음 전체 코드베이스를 재구성하지 않고도 각 모듈 내에서 메커니즘을 변경할 수 있습니다.
Baldrickk

1
@ Baldrickk 추가 답변으로 공유 할 가치가 있다고 말하고 싶습니다. (나는 그것을 찬성했다!) 나의 대답은 처음에 큰 문제가 발생하지 않도록 건축과 계획의 중요성을 건너 뜁니다. "일반적인 프로그램 개발"에 대한 Gizmo의 언급은이 조기 최적화 개념에서 비롯된 것입니다. 위에서 설명한 것처럼 잘못된 최적화는 누락 된 최적화만큼 쉽게 기술적 부채가 될 수 있습니다. 그러나 우리는 의도적으로 느리게 일을하지 않으며, 실제 문제를 프로파일 링하고 찾을 수있을 때까지 단순성과 가독성을 선호합니다.
DMGregory

1
나는 아마도 당신들 중에서 가장 경험이 많지 않지만, 나는이 "모든 악의 조기 최적화 루트"가 약간 이상하다고 말합니다. 2 년 전쯤에 Unity3D에서 무언가를하려고했습니다. 각각 이전 쿼리를 사용하는 LINQ 쿼리를 몇 개 작성했습니다. 나는 내 코드를보고 강한 의문을 가지기 시작했다. 계산 복잡성이 끔찍하다고 생각했습니다. 나는 한 장의 종이를 가져 와서 예상되는 크기의 데이터에 대해 이러한 쿼리를 처리하는 데 몇 시간이 걸릴 것이라고 계산했습니다. 그래서 여기저기서 약간의 캐싱을 추가했습니다. 그리고 쿼리가 제대로 실행되었습니다.
gaazkam

3
따라서 부지런히 수행하고 코드를 처음에 가장 명확하고 직관적 인 코드로 변경하기 전에 문제가 실제인지 확인했습니다. 그것은 최적화가 조기에 이루어지지 않았다는 것을 의미합니다. ;) "조기 초과 최적화하지 마십시오"는 "필요하지 않은 비싼 코드 작성"을 의미하지 않습니다. 단지 명확한 성능 문제가 확인 될 때까지 단순성, 가독성, 수정 용이성을 선호합니다. 의견은 토론을위한 것이 아니므로 이에 대해 더 이야기하고 싶은 경우 채팅으로 이동할 수 있습니다.
DMGregory

42

참고 :이 답변은 DMGregory의 답변에 대한 의견으로 시작되었으므로 그가 작성한 좋은 점을 복제하지 않습니다.

"성능을 염두에두고 처음으로 개발하는 것보다는 게임의 핵심 구조 중 일부를 변경하는 것이 매우 어려울까요?"

이것은 나에게 질문의 핵심입니다.

독창적 인 디자인을 만들 때는 효율성을 높이기 위해 디자인 해야 합니다. 이것은 최적화가 적고 구조에 관한 것입니다.

예 :
강을 건너는 시스템을 만들어야합니다. 명백한 디자인은 다리 또는 페리이므로 어느 것을 선택합니까?
물론 대답은 교차로의 크기와 교통량에 따라 다릅니다. 이것은 최적화가 아니라 문제에 적합한 디자인으로 시작하는 것입니다.

디자인 선택이 제시되면 원하는 작업에 가장 적합한 것을 선택하십시오.

따라서 트래픽 양이 상당히 적다고 말하면 두 개의 터미널을 만들고 페리를 구매하여 트래픽을 처리하기로 결정합니다. 좋은 간단한 구현
불행하게도 일단 설치하고 실행하면 예상보다 많은 트래픽이 발생하는 것으로 나타났습니다. 페리를 최적화해야합니다! (작동하기 때문에 다리를 짓는 것은 좋은 계획이 아닙니다)

옵션 :

  • 두 번째 페리 구매 (병행 처리)
  • 페리에 다른 자동차 데크 추가 (트래픽 압축)
  • 페리 엔진을 업그레이드하여 더 빠르게 만듭니다 (재 작성 처리 알고리즘)

여기에서 가능한 한 원래의 디자인을 모듈 식으로 만들어야합니다.
위의 모든 것은 가능한 최적화이며 세 가지를 모두 수행 할 수도 있습니다.
그러나 큰 구조적 변경없이 어떻게 이러한 변경을 수행합니까?

명확하게 정의 된 인터페이스가있는 모듈 식 설계가있는 경우 이러한 변경 사항을 구현하는 것이 간단 해야 합니다.
코드가 단단히 연결되지 않은 경우 모듈 변경은 주변 구조에 영향을 미치지 않습니다.

페리를 추가하는 방법을 살펴 보겠습니다.
'나쁜'프로그램은 단일 페리의 아이디어를 중심으로 구축 될 수 있으며, 도크 상태와 페리 상태를 가지며 모두 함께 묶여 공유 상태를 유지합니다. 시스템에 추가 페리를 추가 할 수 있도록 수정하기가 어렵습니다.
더 나은 디자인은 독과 페리를 별도의 개체로 만드는 것입니다. 그들 사이에 긴밀한 연결은 없지만 페리가 도착하고 승객을 내리고 새로운 승객을 태우고 떠날 수있는 인터페이스가 있습니다. 도크 및 페리는이 인터페이스 만 공유하므로이 경우 두 번째 페리를 추가하여 시스템을 쉽게 변경할 수 있습니다. 도크는 실제로 페리가 무엇인지 신경 쓰지 않으며, 모든 것이 무엇이든간에 인터페이스를 사용하고 있다는 것입니다.

tl; dr :

  • 우선 효율성을 위해 디자인을 시도하십시오.
  • 두 가지 선택 사항이 제시되면보다 효율적인 선택 사항을 선택하십시오.
  • 잘 정의 된 인터페이스로 가능한 한 모듈 식으로 코드를 작성하십시오.

그런 다음 최적화해야 할 때 전체 코드베이스를 재구성하지 않고도 각 모듈 내에서 메커니즘을 변경할 수 있습니다.


16
처음에는 페리를로 구현할 수 IRiverCrossing있으며 페리 설정에 비해 트래픽 양이 너무 많다는 것이 확인되면 브리지를 구현 IRiverCrossing하고 떨어 뜨립니다. 물론 비법은 페리의 외부 API를 줄이는 것입니다. 동일한 기능으로 표시 될 수 있도록 공통 기능으로의 브리지.
Mr.Mindor

2
이러한 모듈 식 인터페이스에 대해 자동화 된 테스트를 작성했을 수도 있으므로, 터치하고있는 모듈 외부의 모든 것을 깨뜨리지 않고 빠르게 리팩토링 할 수 있습니다.
user3067860

2
요즘 OOP가 왜 중요한지에 대한 아주 좋은 예입니다.
Jaime Gallego

1
당신은 올바른 이유를 명중했습니다. Donald Knuth의 진언은 속도가 핵심 요구 사항 중 하나가 아닌 경우에만 적용되며 최적화에 중점을두면 주 설계가 손상 될 수 있습니다. 아아, 게임은 종종 속도 이다 핵심, 따라서 초기에 설계에 반영해야합니다. OP의 관심사 및 귀하의 답변은 전적으로 정당합니다.
피터 A. 슈나이더

3
@AlexandreVaillancourt는 질문 제목에 대답하는 대신 실제로 답변되는 질문의 핵심 부분이라고 생각하는 것에 대답하려고 노력했습니다. 즉, "내 디자인이 고정되어 있기 때문에 최적화하는 것은 나중에 더 많은 일을 할 것인지 일찍 최적화 안되는 이유"(의역) . 이 답변은 또한 DMGregory의 답변에 대한 의견으로 시작되었으며 그 외에 추가되며 그의 답변을 복제 할 필요는 없습니다.
Baldrickk

24

"조기 최적화하지 않는다"는 것이 "가장 최악의 일을하는 방법을 선택"을 의미하지는 않습니다. 프로토 타입을 작성하지 않는 한 여전히 성능에 미치는 영향을 고려해야합니다. 요점은 융통성, 신뢰성 등과 같이 개발의 그 시점에서 다른 더 중요한 것들을 무너 뜨리지 않는 것입니다. 간단하고 안전한 최적화를 선택하십시오. 비용을 추적하십시오. 강력한 타이핑을 사용해야합니까? 대부분의 게임은 잘 작동했습니다. gamemplay에 대한 유연성의 흥미로운 사용법을 발견 한 경우이를 제거하는 데 얼마나 많은 비용이 듭니까?

최적화 된 코드, 특히 "스마트"코드를 수정하는 것이 훨씬 어렵습니다. 그것은 항상 어떤 것을 더 좋게 만들고 다른 것은 더 나쁘게 만드는 선택입니다 (예를 들어, 메모리 사용을 위해 CPU 시간을 거래 할 수 있습니다). 그 선택을 할 때, 당신은 모든 의미를 알고 있어야합니다. 그것들은 비참 할 수도 있지만 도움이 될 수도 있습니다.

예를 들어 Keen, Wolfenstein 및 Doom 사령관은 각각 최적화 된 렌더링 엔진 위에 구축되었습니다. 각 게임에는 "트릭"이있어서 게임을 처음부터 사용할 수있었습니다 (각각 시간이 지남에 따라 추가 최적화가 있었지만 여기서는 중요하지 않습니다). 괜찮습니다 . 게임의 핵심, 게임을 가능하게하는 생각을 크게 최적화해도 괜찮습니다. 특히이 최적화 된 기능을 통해 새로운 영역을 탐색하는 경우 많이 탐색하지 않은 게임 디자인을 고려할 수 있습니다. 최적화가 도입 한 제한은 흥미로운 게임 플레이를 제공 할 수도 있습니다 (예 : RTS 게임의 단위 수 제한은 성능을 개선하기위한 방법으로 시작되었지만 게임 플레이 효과도 있습니다).

그러나 이러한 각 예에서 게임은 최적화 없이는 존재할 수 없었습니다. 그들은 "완전히 최적화 된"엔진으로 시작하지 않았습니다. 그들은 맨 필요로 시작하여 일을 시작했습니다. 그들은 새로운 기술을 개발하고 재미있는 게임을 만드는 데 사용했습니다. 그리고 엔진 트릭은 가능한 한 코드베이스의 작은 부분으로 제한되었습니다. 더 무거운 최적화는 게임 플레이가 대부분 수행되었을 때 또는 흥미로운 새로운 기능이 등장 할 때만 도입되었습니다.

이제 만들고 싶은 게임을 생각해보십시오. 그 게임을 만들거나 깨는 기술 기적이 실제로 있습니까? 아마도 당신은 무한한 세상에서 열린 세계 게임을 상상하고있을 것입니다. 즉 정말 게임의 중앙 조각? 게임이 없으면 단순히 작동하지 않습니까? 어쩌면 당신은 현실적인 지질학 등으로 지형이 제한없이 변형 될 수있는 게임에 대해 생각하고있을 것입니다. 더 작은 범위에서 작동하게 할 수 있습니까? 3D 대신 2D로 작동합니까? 최적화로 인해 기존 코드의 큰 덩어리를 재 작업해야 할 경우에도 가치가있을 수 있습니다. 더 큰 물건을 만들어도 게임이 더 나아지는 것은 아니라는 것을 깨달을 수도 있습니다.

많은 최적화가 적용된 최근 게임의 예로서, Factorio를 지적하겠습니다. 게임의 중요한 부분 중 하나는 벨트입니다. 수천 개가 있으며 공장 주변에 많은 개별 재료를 운반합니다. 게임이 최적화 된 벨트 엔진으로 시작 되었습니까? 아니! 사실, 원래 벨트 디자인은 최적화하기가 거의 불가능했습니다. 벨트에있는 항목을 물리적으로 시뮬레이션 한 결과 흥미로운 일이 생겼습니다 (이것은 "긴급한"게임 플레이를 얻는 방식입니다-놀라운 게임 플레이입니다). 디자이너), 그러나 벨트의 모든 단일 항목을 시뮬레이션해야 함을 의미했습니다. 수천 개의 벨트를 사용하면 수만 개의 물리적으로 시뮬레이션 된 항목을 얻을 수 있습니다. 심지어이를 제거하고 벨트로 작업을 수행하면 관련 CPU 시간을 95-99 % 줄일 수 있습니다. 메모리 로컬 리티와 같은 것을 고려하지 않아도 그러나 실제로 해당 한계에 도달 할 때만 유용합니다.

벨트와 관련이있는 거의 모든 것이 벨트가 최적화되도록 벨트를 다시 만들어야했습니다. 대형 공장에는 많은 벨트가 필요했으며 대형 공장이 게임의 매력 중 하나이기 때문에 벨트를 최적화해야했습니다. 결국, 큰 공장을 가질 수 없다면 왜 무한한 세상을 가지고 있습니까? 재밌게 물어봐야한다-초기 버전 은 그렇지 않았다 :) 게임이 재 작업되어 현재 위치를 찾기 위해 여러 번 재 형성되었다. 이 같은 게임을하고 C ++로 전환했습니다. 그리고 Factorio에게는 훌륭하게 작동했습니다 (아직도 프로젝트에서 최적화되지 않은 것이 좋지만-특히 취미 프로젝트로 관심이 없기 때문에 실패했을 수도 있습니다).

그러나 일이있다 있습니다제한된 범위의 공장에서 할 수있는 많은 일들이 있습니다. 많은 게임들이 그 사실을 보여주었습니다. 한계는 자유보다 재미를 더 강화할 수 있습니다. "지도"가 무한하다면 Spacechem이 더 재미 있을까요? 많이 최적화 된 "벨트"로 시작했다면 거의 그렇게해야합니다. 물리 시뮬레이션 컨베이어 벨트로 수행 할 수있는 흥미로운 작업을 확인하는 등 다른 설계 방향을 탐색 할 수 없었습니다. 잠재적 인 디자인 공간을 제한하고 있습니다. 완료되지 않은 게임이 많이 보이지 않기 때문에 어려운 부분이 재미를 얻습니다. 재미있는 게임마다 수백 가지가있을 수 있습니다. 끔찍한 혼란으로 풀려 나갔습니다). 최적화가 도움이된다면 계속하십시오. 그렇지 않으면 ... 아마도 조기 일 것입니다. 일부 게임 플레이 메커니즘이 훌륭하게 작동한다고 생각하지만 진정으로 빛을 발하기 위해서는 최적화가 필요합니다. 흥미로운 역학이 없다면최적화하지 마십시오 . 재미를 먼저 찾으십시오-대부분의 최적화가 도움이되지 않으며 종종 해 롭습니다.

마지막으로, 당신은 훌륭하고 재미있는 게임이 있습니다. 지금 최적화하는 것이 이치에 맞 습니까? 하아! 생각만큼 명확하지 않습니다. 재미 있나요대신 할 수 있습니까? 시간이 여전히 제한되어 있음을 잊지 마십시오. 모든 것이 노력이 필요하며, 그 노력을 가장 중요한 부분에 집중하려고합니다. 예, "무료 게임"또는 "오픈 소스"게임을 만드는 경우에도 마찬가지입니다. 게임이 어떻게 진행되는지보십시오. 성능에 병목 현상이 발생하는 위치를 확인하십시오. 그 장소를 최적화하면 더 큰 즐거움을 얻을 수 있습니까? 더 많은 플레이어를 유치 할 수 있습니까 (예 : 컴퓨터가 약하거나 다른 플랫폼에서)? 항상 우선 순위를 정해야합니다. 비율을 산출하는 노력을 찾으십시오. 게임을하고 다른 사람들이 게임을하는 것을 보는 것만으로도 낮은 성과를 거둘 수 있습니다. 그러나 중요한 부분을 참고하십시오-거기에 가려면 게임이 필요합니다 . 그것에 집중하십시오.

체리로서 최적화는 결코 끝나지 않는다는 것을 고려하십시오. 작은 확인 표시가있는 작업이 아니라 다른 작업으로 넘어갑니다. 항상 "한 번 더 최적화"할 수 있으며, 개발의 큰 부분은 우선 순위를 이해하는 것입니다. 최적화를 위해 최적화를 수행하지 마십시오. 특정 목표를 달성하기 위해 수행합니다 (예 : "333 MHz Pentium에서 한 번에 200 개의 화면을 표시하는 것이 좋습니다"). 더 이상 터미널 목표의 전제 조건이 아닐 수도있는 중간 목표에 너무 집중하여 터미널 목표를 추적하지 마십시오.


팩토리 오 개발자들은 이제 벨트를 다시 최적화 하여 아이템을 주기적으로 시뮬레이션하기 만하면되며, 다른 시점에서 보았을 때 위치를 보간 하기 만합니다 . 그러나 그들은 단지 것을하고있는 지금은 전체 게임을 효과적으로 벨트 (로봇) 오랫동안 기반으로 한 때 하지 때까지 사람들이 알아 차리지 및 성능에 대해 불평하기 시작했다.
immibis

2
@immibis 정확합니다. 사람들이 실제로 한계에 도달하기 전에 성능을 향상시키는 것은 자원 낭비이며 다른 곳에서 더 잘 소비됩니다. 최신 최적화를 사용하더라도 일반적인 게임 플레이 범위를 벗어나는 초소형 공장에서만 문제가 발생할 가능성이 높습니다 (로켓 시작). 그러나 훨씬 더 큰 물류가 필요한 새로운 Marathon 게임 플레이 설정을 가능하게했습니다. 그리고 다시, 그들은 실제로 게임을하는 사람들로부터 통계를 얻어 병목 현상을 식별했습니다. 병목 현상의 약 절반은 그들에게 큰 놀라움이었습니다.
루안

@Fattie 그래서 당신은 질문을 이해하지만 대답은 아닙니까? 더 간단한 답변이 가능하다고 말하려고하십니까 (예 : "경제학")? 귀하의 의견이 건설적인 것으로 보지 못했습니다.
Luaan

2
@Fattie 답이 "병목 현상이 무엇인지 알고 나면 최적화"라고 생각하면 답으로 게시하십시오. 좋은 답변을 얻는 데 필요한 것보다 더 많은 단어를 이미 사용 했으므로 계속하십시오. 어떤 종류의 최적화가 일을 더 나쁘게 만들지 않습니까? 나는 결코 본 적이 없다. 내가 계속 반복하는 근본적인 점은 항상 다른 곳에서 더 잘 사용할 수있는 절충 시간, 유연성을 제한하는 복잡성이라는 것입니다. 예제는 "초기"가 절대적인 용어가 아니라고 지적합니다. 어떤 최적화는 첫날부터 필요한 반면 다른 최적화는 해 롭습니다.
루안

1
@Fattie "병목 현상이 무엇인지 알고 나면 최적화"는 "언제 최적화해야합니까?"에 대한 답변입니다. "너무 일찍 최적화하는 것이 왜 그렇게 나쁘지?"에 대한 답 이 아닙니다 .
immibis

10

많은 답변이 "최적화"의 성능 측면에 많은 초점을 맞추고있는 반면, 저는 저 자신을 최적화와 너무 추상적 인 수준에서 너무 일찍 최적화하는 전체 시련을보고 싶습니다.

폴리 노 미노의 도움으로 내 관점을 자세히 설명하려고 할 때 유머러스합니다.

작업중인 프레임 워크 또는 엔진에 의해 설정된 고정 된 경계가 있다고 가정합니다.

여기에 이미지 설명을 입력하십시오

그런 다음 게임의 첫 번째 레이어 / 모듈을 만듭니다.

여기에 이미지 설명을 입력하십시오

계속해서 두 번째 레이어 / 모듈을 만듭니다.

여기에 이미지 설명을 입력하십시오

이 시점에서, 우리는 두 모듈 사이에 사용 가능한 공간이 있음을 알 수 있으며 우리에게 할당 된 경계를 최대한 활용하도록 최적화하려고 할 수 있습니다.

여기에 이미지 설명을 입력하십시오

완벽합니다. 이제 응용 프로그램이 사용 가능한 리소스를 완전히 활용하고 있습니다. 응용 프로그램이 더 좋습니다.

우리는 응용 프로그램의 세 번째 레이어 / 모듈을 구축하기 시작했고 갑자기 세 번째 레이어 / 모듈이 작동하지 않는다는 것을 깨달았습니다 (아마도 초기 계획 중에 예측할 수 없었던 것조차도).

우리는 대안을 찾고, 하나를 찾게되고, 결국 우리는 새로 선택된 3 번째 모듈과 호환되지 않기 때문에 2 번째 모듈을 변경해야합니다. (다행스럽게도 첫 번째 모듈과 다소 호환되므로 처음부터 모든 것을 다시 작성할 필요가 없습니다.)

그래서 우리는 그것을 모두 모았습니다 ...

여기에 이미지 설명을 입력하십시오

흠, 무슨 일이 있었는지 알아?

너무 일찍 최적화함으로써 우리는 실제로 우리가 최적화 한 것이 결국 줄을 잃은 것이 아니기 때문에 실제로 효율성을 악화시킵니다.

그리고 나중에 추가 모듈 또는 추가 tidbit를 추가하고 싶었다면 더 이상이 시점에서 수행 할 수있는 용량이 없을 수도 있습니다.

여기에 이미지 설명을 입력하십시오

그리고 우리 시스템의 가장 낮은 레벨을 조정하는 것은 다른 모든 레이어 아래에 묻혀 있기 때문에 더 이상 실현 가능하지 않습니다.

그러나 즉시 최적화하려는 충동을 기다리면 다음과 같은 결과가 나타납니다.

여기에 이미지 설명을 입력하십시오

이제이 시점에서 최적화를 수행하면 만족스러운 결과를 얻을 수 있습니다.

여기에 이미지 설명을 입력하십시오

잘만되면 적어도 당신 중 일부는 내가 이것을 재미있게 만드는 것처럼 이것을 읽는 것이 재미있었습니다.) 당신이 지금 당신이 주제에 대해 더 잘 이해하고 있다고 느끼면-모두 더 좋습니다.


3
광고를 제거하고 있습니다. 우리는 당신이 이미지를 어떻게 만들 었는지 상관하지 않습니다. 유일한 중요한 부분은 귀하가 게시 할 권리가 있다는 가정입니다.
Gnemlock

2
@Gnemlock 공정한, 내 의도가 광고를 목표로하지 않았지만 어떻게 쉽게 잘못 해석 될 수 있는지 알 수 있으며 대답에 아무것도 추가하지 않아서 거기에 자리가 없다는 데 동의합니다.
Ceiling Gecko

2
이 시각적 은유가 매우 효과적이라고 생각합니다. 질문에 대한 훌륭한 접근 방식! :)
DMGregory

8

돈.

그것은 그것으로 귀착됩니다. 돈. 시간은 돈이기 때문에 * 더 많은 돈을 벌 수 있다고 보장되지 않는 활동에 더 많은 시간을 투자할수록 (즉 , 이러한 활동을 투자 로 간주 할 수 없음 ), 낭비하는 돈이 더 많고 돈을 덜 벌게됩니다 게임.

여기에 몇 가지 더 있습니다 가능성이 너무 일찍 최적화의 부작용, 그리고 이유가 왜 당신은 그것을 피해야한다 :

  • 장난감을 가지고 샌드 박스에서 놀러 가기 때문에 동료들이 당신을 미워합니다.
  • 지연은 더 높은 관리를 불쾌하게 만들고 팀이 배달 날짜를 놓치게하여 휴가 시즌이 아닌 봄에 게임이 출시되어 게임이 충분히 팔리지 않습니다. 이 때문에 본사는 스튜디오를 종료하기로 결정하고 효과적으로 실직하게 만듭니다. 그리고 직업이 없다는 것은 돈이 없다는 것을 의미합니다. (그리고 조기 최적화에 너무 많은 시간을 보냈기 때문에 아무도 당신을 좋아하지 않기 때문에 아무도 LinkedIn에서 당신을 위해 당신의 작업에 대해 긍정적 인 리뷰를 작성하고 싶지 않아서 더 이상 돈을 버리지 않을 것입니다.)

* 다른 답변은 '시간'부분을 충분히 강조했습니다.


부수적 으로 , 일반적으로 경험은 무엇이 조기 최적화가 아닌지, 비즈니스에 가치가있는 것과 그렇지 않은 것을 결정하는 데 도움이됩니다.

예를 들어, 게임 A에서 작업하고 프로젝트 끝에서 XYZ 기능이 게임 루프에서 특히 무거웠다는 것을 깨달았을 때 결국 동일한 기능을 가진 게임 B에서 작업하기 시작합니다. 기능을 다시 작성하고 처음부터 최적화하는 것이 실제로 조기 최적화되지는 않습니다. 아무것도 작성하지 않으면 병목 현상이 발생한다는 것을 알기 때문에 .


1
유효한 점인 @JBentley. 그러나 수집 된 경험에 직접적인 영향을 미치는 "왜"에 대한 결과적인 대답이 있습니다. 따라서 1) 조기 최적화는 평균 런타임에 영향을 미치지 않는 코드 부분에서 시간 낭비로 이어질 수 있습니다 (경험이 주어지면 어떤 코드 구조가 최적화 모범 사례의 후보 인지 알아야 함 ) 2) 조기 최적화는 코드를 더 어렵게 만들 수 있습니다 일부 시스템에 적용되는 설계 제한으로 인해 유지 관리. 따라서 개발주기가 길고 번거로운 코드를 유지하기에는 비용이 너무 적게들 수 있습니다.
teodron

3
@JBentley 이것을 DMGregory의 답변에 대한 부록으로 생각하십시오.
Alexandre Vaillancourt

1
이것은 여기서 유일하게 가치있는 답변 인 것 같습니다. 질문은 긴장입니다. 당신은뿐만 아니라 요청할 수도 있습니다 "는 앱 스토어에 적은 돈보다 오히려하게 왜, 실제로, 당신이 원하는 않는 게임을?" 어떻게 대답 할 수 있습니까?
Fattie

@Fattie 답변에 이런 종류의 관점을 갖는 것이 좋습니다. 그러나 그것이 유일하게 가치있는 답이라고 말하는 것은 질문의 범위를 부당하게 좁히는 것입니다. 예를 들어, 제작 된 유일한 게임은 영리 조직 내에 있다고 가정합니다 (확실히 사실이 아님). 또한 OP를 조기에 최적화하면 더 많은 시간을 소비하게되므로 비즈니스에 대해 더 많은 돈을 벌게된다는 것이 분명합니다. 실제로 OP의 질문은 그가 이것에 대해 확신하지 못한다는 것을 보여줍니다.
JBentley

6

정의에 따르면 최적화는 솔루션의 효율성이 저하되는 지점까지 솔루션의 효율성을 높이는 프로세스입니다. 이 과정은 솔루션 공간의 축소를 의미합니다.

소프트웨어 개발 초기 단계에는 여전히 "숨겨진 요구 사항"이있을 수 있습니다. 솔루션의 공간을 너무 많이 줄이면 팝업이 표시 될 때 "숨겨진 요구 사항"을 충족시킬 수없는 상황이 발생할 수 있습니다. 개발의 후반 단계에서 이러한 방식으로 불안정성과 예상치 못한 행동을 추가하여 아키텍처를 수정하도록 강요합니다.

아이디어는 전체 솔루션을 작동시키고 모든 요구 사항이 수정되고 구현 될 때만 코드를 강화하는 것입니다. 그러면 코딩하는 동안 한 번에 가볍게 구현 한 많은 최적화가 더 이상 요구 사항과의 상호 작용으로 인해 더 이상 실현 가능하지 않다는 것을 알 수 있습니다.

솔루션의 실제 공간은 매우 복잡한 시스템에 대한 완벽한 지식을 가질 수 없기 때문에 처음에 예상 한 것보다 항상 더 큽니다.

먼저 작동 시키십시오. 그런 다음 로프를 조입니다.


2
"효능"은 당신이 원하는 단어가 아니라고 생각합니다. 그것은 "효과를 만들어내는 힘"을 의미합니다. 어떤 의미에서, 최적화는 효능을 높이는 것 입니다. 특정 버전의 효능을 원하십니까? (당신은 그것에 연결할 수 있습니까?) 대신 유연성과 같은 것을 의미합니까?
doppelgreener

2
@doppelgreener 그것은 당신이 원하는 효과를 멈출 때까지 솔루션을보다 효율적으로 만드는 것을 의미합니다 ...
immibis

1
"먼저 작동 시키십시오. 그런 다음 로프를 조이십시오." -나머지 답변을 합한 것만 큼 가치가 있어야합니다. 그리고 다른 것들이 좋지 않다는 것은 말할 것도 없습니다.
ebyrob

1
@ebyrob : 또 다른 말이 있습니다 : "작동하게하고, 올바르게 만들고, 빠르게 만드십시오" wiki.c2.com/?MakeItWorkMakeItRightMakeItFast
ninjalj

@ninjalj 그것도 좋은 것입니다. 물론 상사는 항상 이렇게 말합니다. "서두르지 말고 올바르게 만드십시오." 그래서 나는 당신이 말하는 것이 원래 포스터가 더 자세하게 요구하는 교장만큼 보편적인지 모르겠습니다.
ebyrob

2

요컨대, 나중에 변경하고 싶을 때 초기 최적화는 종종 낭비되는 노력이되고, 쉽게 변경 가능한 코드 구조를 훨씬 낮은 수준으로 최적화 한 다음 다시 높은 수준으로 변경해야합니다. 수준 접근, 결과를 다시 한 번 최적화하십시오.

이것은 최적화와 같이 "유용한 작업을 수행하는 것"에서 즐거움을 얻는 데 초점을 맞추고 싶어하는 초보자 개발자에게는 일반적인 실수입니다. 게임과 같은 대규모 프로젝트를 프로그래밍 한 경험이 있으면 기존 코드베이스를 최적화해야 할 시점과 너무 빠른시기를 알게됩니다. 이 실수를 두려워하지 말고 배우는 것만으로도 이익을 얻을 수 있습니다.

일반적으로 현재 개발 빌드로 작업 할 수없는 경우에만 최적화하십시오. 초당 60 회 수백만 개의 개체를 만들고 삭제하는 것처럼.

따라서 학습 경험 측면에서 초기에 몇 번 최적화하는 것이 좋습니다 .p


2

최적화는 컴퓨터가 코드에서 가장 잘 작동하도록하는 데 초점을 맞추고 개발에는 프로그래머가 코드에서 가장 잘 작동하도록해야합니다.

최적화는 통찰력을 얻지 못합니다. 컴퓨터의 작동을 줄이고 프로그래머의 능력을 향상시킵니다.

물론 자동차 디자인과 같은 다른 카테고리가 있습니다. 첫 번째 섀시를 구축하기 전에 엔진을 최적화하는 데 아무런 문제가 없지만 엔진의 모양을 모르기 전에 섀시를 최적화하면 시간이 낭비 될 수 있습니다. 모듈성 및 사양은 제품 전체가 조립되기 전에도 최적화 작업을 수행 할 수있는 여러 장소를 확보 할 수 있습니다.


이것은 최적화를 정의하는 것 이외의 다른 것을 이끌고 자동차에 대한 비유보다는 게임 개발의 실제 상황에 대해 이야기함으로써 개선 될 것입니다.
doppelgreener

tautological 질문에 대한 완벽한 답변.
Fattie

2

코드가 초기 단계에서 최적화되어서는 안된다는 모든 진술에 동의하지 않습니다. 그것은 당신이 어떤 단계에 달려 있습니다. 이것이 MVP 인 프로토 타입이고 1-2 주 정도 걸리는 게임을 보려고한다면 이미 작성한 모든 것을 다시 쓸 준비가 된 것입니다. 예, 최적화는 중요하지 않습니다. 그러나 이미 출시 될 게임을 개발 중이라면 코드를 최적화해야합니다. 사람들이 새로운 기능과 추가 할 수있는 것들에 대해 이야기하는 것은 잘못된 개념입니다. 최적화 된 코드가 아니라 코드 아키텍처가 잘못 설계되었습니다. 멋진 코드 디자인이 있다면 새로운 요소를 추가하기 위해 아무것도 다시 작성할 필요가 없습니다.

예를 들어, A * 경로 찾기 알고리즘이 있다면 가장 최적의 방법으로 작성하는 것이 좋지 않을까요? 나중에 다른 메소드 호출과 콜백이 필요하기 때문에 알고리즘을 약간 변경해야했기 때문에 나중에 코드의 절반을 변경하는 대신? 그리고 이미 시작부터 최적화 된 코드를 가지고 있다면 많은 시간을 절약 할 수 있습니다. 맹목적으로 수많은 새 스크립트를 작성하고 모든 연결을 즉시 구성하는 대신 객체와 객체 간의 상호 작용 방식을 직접 파악할 수 있기 때문에 불분명 한 sphagetti 코드가 생성됩니다.

마지막으로 추가하고 싶은 것은 나중에 게임을 더 이상 만들고 싶지 않더라도 다음 게임에 사용할 수있는 최적화 된 A * 알고리즘이 있다는 것입니다. 재사용 성. 예를 들어, 많은 게임에는 인벤토리, 길 찾기, 절차 생성, npc 간의 상호 작용, 전투 시스템, AI, 인터페이스 상호 작용, 입력 관리가 있습니다. 이제 스스로에게 물어봐야합니다. "그 요소들을 처음부터 몇 번이나 다시 썼습니까?" 그들은 게임의 70-80 %입니다. 항상 다시 작성해야합니까? 최적화되지 않은 경우 어떻게해야합니까?


5
A * 코드가 최적화되기 시작하면 "최적화"는 어떻게 최적화됩니까? 벤치 마크를 수행하기 전에 어셈블리의 작업을 핸드 코드합니까? 나는 벤치마킹이 끝날 때까지 일반적으로 미세 최적화에 대한 사소한 작업을 남겨 두어야한다고 생각합니다. 최적화 컴파일러 마이크로 최적화보다 더 나은 작업을 수행 수 있으며 훨씬 저렴합니다.
gmatht

@gmatht Well A *는 디자인이 좋지 않고 제대로 작동하지 않는다고 말한 것처럼 다를 수 있습니다. 그러나 피보나치 힙을 기반으로 멀티 스레드가 가능하며 예측이 있으며 덩어리로 나뉩니다. 길 찾기에 대해 이야기하고 있다면 Flow Field를 추가하여 A *와 혼합 할 수 있습니다. 또한 부드럽게 다듬기. 어쩌면 A *가 가장 좋은 예는 아니지만 최적화는 실제로 코드를 변경하는 것과 아무런 관련이 없으며 개발자는 코드가 잘못 설계 되었기 때문에 코드를 변경하고 있습니다. 예를 들어 그는 SOLID를 1 가지 이유로 따르지 않았습니다. 이 A *를 잘 쓰면 더 이상 쓸 필요가 없습니다.
솔직한 달 _Max_

@gmatht 마이크로 최적화는 실제로 문제가 아닙니다. 나는 OP가 AI 행동이나 쉐이더 또는 다른 어떤 것을 계산하는 가장 좋고 가장 효율적인 방법을 의미한다고 생각합니다.
솔직한 달 _Max_

이 글을 효율적으로 작성하는 방법을 알고 있다면 문제가 발생하지 않습니다. 같은 시간 또는 더 적은 시간이 걸립니다. 개발자 경험에 더 의존합니다. 프로그래머로서 더 나은 솔루션을 알고 있다면 엉뚱한 해결책을 쓰지 않을 것입니다. 피보나치 힙을 작성하는 방법을 알고 있다면 List와 sorting을 사용하여 최소 또는 최대 값을 얻지 않습니다. 물론 List.Sort ()를 사용하는 대신 작성하는 데 더 많은 시간과 노력이 필요합니다. 하지만 이미 재사용 가능한 제품이 있다면 어떻게해야합니까?
솔직한 달 _Max_

2
@CandidMoon "동일한 시간이 소요될 것입니다."에 동의하지 않습니다. 효율적인 코드를 작성합니다. 어쩌면 비효율적이지 않은 코드를 작성하는 데 같은 시간이 걸릴 수 있지만, "효율"이라는 개념이 캐시 경합을 고려하고, 멀티 스레딩을 추가하고, 일부 CPU에서만 사용 가능한 CPU 고유의 내장 함수를 사용하여 O로 인해 큰 N에 대한 알고리즘을 전환하는 것을 의미 할 때 O (N) 대 (N N 로그) - 그런 종류는 하드쉬운 오류 와 간단한 구현보다 더 많은 시간이 걸립니다. 최종 결과에 실질적으로 영향을 줄 것임을 알고 있을 때만 수행하십시오 .
마이클 앤더슨
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.