단순 vs 복합 (성능 효율적인) 솔루션 – 언제 어느 것을 선택해야합니까?


28

나는 몇 년 동안 프로그래밍을 해왔으며 종종 딜레마에 빠졌다.

두 가지 해결책이 있습니다-

  • 하나는 간단한 것입니다. 즉, 간단한 접근 방식, 이해하기 쉽고 유지하기가 쉽습니다. 여기에는 중복성, 추가 작업 (추가 IO, 추가 처리)이 포함되므로 최적의 솔루션이 아닙니다.
  • 그러나 다른 것들은 복잡한 접근 방식을 사용하여 구현하기 어렵고 종종 많은 모듈 간의 상호 작용을 포함하며 성능 효율적인 솔루션입니다.

충족 할 수없는 성능 SLA가없고 간단한 솔루션으로도 성능 SLA를 충족 할 수있는 경우 어떤 솔루션을 사용해야합니까? 동료 개발자들 사이에서 간단한 해결책에 대해 경멸감을 느꼈습니다.

간단한 솔루션으로 성능 SLA를 충족 할 수있는 경우 가장 최적의 복잡한 솔루션을 만드는 것이 좋은 방법입니까?


10
참조 : 어떻게 "개발자의 나쁜 최적화 직관"을 피할 수 있습니까? "안타깝게도 개발자는 일반적으로 응용 프로그램의 성능 문제가 실제로 발생하는 위치에 대해 끔찍한 직감을 가지고 있습니다."
gnat

1
"가장 최적이 아님"이 여전히 "충분히 좋을 것"입니까? 그런 다음 그 상태를 유지하십시오.

8
네. " Le mieux est l' ennemi du bien. "볼테르. ( "완벽한 사람은 선의 적입니다.") 성능 테스트에서 달리 말할 때까지는 충분하면 충분합니다.
David Hammen

나는 일반적으로 단순한 것이 효율적임을 암시합니다. 따라서 종종 타협 할 필요가 없습니다.
Dan

2
"추가 할 것이없고, 더 이상 제거 할 것이 없을 때 완벽 함이 달성 된 것 같습니다."– Antoine de Saint-Exupery
keuleJ

답변:


58

충족 할 수없는 성능 SLA가없고 간단한 솔루션으로도 성능 SLA를 충족 할 수있는 경우 어떤 솔루션을 사용해야합니까?

간단한 것. 사양을 충족하고 이해하기 쉽고 유지 관리가 쉽고 버그가 적습니다.

성능 효율적인 솔루션을 옹호하기 위해 수행하는 일은 코드에 투기 일반 성과 조기 최적화를 도입하는 것입니다. 하지마! 성능은 다른 모든 소프트웨어 엔지니어링의 '유연성'(신뢰성, 유지 관리 성, 가독성, 테스트 가능성, 이해도 등)에 반합니다. 테스트시 체이스 성능은 실제로 퍼포먼스 후 추적이 필요하다는 것을 나타냅니다.

성능이 중요하지 않은 경우 성능을 추적하지 마십시오. 중요하더라도 테스트 결과 성능 병목 현상이 존재하는 영역에서만 성능을 추적해야합니다. simple_but_slow_method_to_do_X()단순한 버전이 병목 현상으로 표시되지 않는 경우 성능 문제가 더 빠른 버전 으로 대체 될 수있는 변명으로 두지 마십시오 .

수많은 코드 냄새 문제로 인해 성능이 향상 될 수밖에 없습니다. 당신은 질문에서 여러 가지를 언급했습니다 : 복잡한 접근법, 구현하기가 어렵고 높은 결합. 정말 드래그 할 가치가 있습니까?


귀하의 답변이 매우 도움이됩니다
MoveFast

1
가능한 한 단순하지만 단순하지는 않습니다. 최대한 빠르지 만 빠르지는 않습니다. etc
user606723

2
"의심
스럽다면

코드의 주석은 여기에서 cathartic하고 도움이 될 수 있습니다. 복잡한 + 빠른 솔루션을 지적하는 작은 의견과 솔루션을 사용하지 않은 이유는 최적의 알고리즘을 무시한 것처럼 느낄 수 있습니다. 또한 유지 보수 담당자가 사용자의 선택을 이해하고 나중에 최적화가 실제로 필요한 경우 올바른 방향을 가리킬 수 있습니다.
TheAtomicOption

12

짧은 답변 : 복잡한 솔루션보다 간단한 솔루션을 선호하고 KISS 및 YAGNI 원칙을 기억하십시오.

초기 프로젝트 요구 사항 및 소프트웨어는 완벽하지 않으므로 응용 프로그램을 개발 / 사용함에 따라 변경이 필요합니다. 개발 단계에서 반복적 인 접근 방식은 간단한 작업을 시작하고 필요에 따라 확장하는 데 매우 적합합니다. 가장 간단한 솔루션은 유연성을 유지하고 관리하기가 더 쉽습니다.

또한, 애플리케이션을 구축하면서 스마트하고 일부 애드혹 최적화를 시도하는 것은 좋은 습관이 아니며 솔루션을 지나치게 복잡하게 만들 수 있습니다. 알려진 바와 같이 "premature optimization is the root of all evil"-Knuth의 책에서


1
@ManojGumber, 아무 문제도없고 프로그래머로서 우리가 무엇을 먼저 관리해야하는지에 대한 본질.
EL Yusubov

8

Knuth의 교훈을 얻으십시오. "시간의 약 97 %라는 작은 효율성을 잊어야합니다. 조기 최적화는 모든 악의 근원입니다."

솔루션은 다음 순서대로 생각하십시오. 첫째, 항상 정확합니다. 둘째, 명확성과 단순성을 향상시킵니다. 셋째, 필요를 입증 할 수있을 때만 효율성.

효율성을 추가하면 거의 항상 중요한 비용이 들기 때문에 필요할 때만 찾아야합니다.


4
이것이 처음에 좋은 구현을 작성해서는 안된다는 것을 의미하지는 않습니다.

@ ThorbjørnRavnAndersen : 물론, 그것은 처음 두 지점에 관한 것입니다.
simon

1
@simon 인용구는 빈약하게 선택하는 변명으로 자주 사용됩니다.

두 번째 요점에 대해 : 나는 올바른 스파게티를 만들기 전에 잘못 구조화되고 깨끗한 코드를 선호한다고 말하는 동료가있었습니다.
Buhb

무능한 사람들은 변명을 위해 무엇이든 사용할 것입니다. 원래 생각의 가치에 영향을 미치지 않습니다.
simon

7

단순성은 신뢰성의 전제 조건입니다 . 작동하는 간단한 솔루션이 있다면 꼭 해결하십시오! 최적화 된 프로그램을 작동시키는 것보다 작업 프로그램을 최적화하는 것이 훨씬 쉽습니다. 또한 무어의 법칙도 잊지 마십시오 . 간단한 솔루션이 오늘날의 성능 목표를 달성하면 1 년에서 2 년 내에 1 을 분쇄 할 수 있습니다 .


1 Jimmy Hoffa가 아래의 주석에서 언급했듯이 무어의 법칙에는 한계가 있기 때문에 보장 할 수 없습니다 .


당신은 무어의 다른 법칙에 대해 잊어 버렸습니다. "죄송합니다. 내 첫 법칙에 대해." 나는 당신의 나머지 부분에 동의하지 않습니다. 나는 적어도 마지막 부분에서주의 할 것입니다.
Jimmy Hoffa

2
죄송하지만이 업계에 대한 모든 경험에서 말입니다. "작업 세트"는 지속적으로 업그레이드되는 하드웨어 속도보다 FAR이 빠르게 증가합니다. 실제로, 나는 단지 무어의 법칙을 제거 할 것입니다.
user606723

@ user606723 "작업 세트"포인트의 증가는 "최적화 또는 단순"질문과 직교합니다. 어떤 솔루션을 구현하든 워크로드가이를 따라 잡습니다. 무어의 법칙을 혼합 한 시점은 간단한 솔루션이 작성 시점에 약간의 성능 압박을 받더라도 더 빠른 하드웨어를 사용할 수있게되면서 압력이 줄어든다는 점을 지적해야했습니다.
dasblinkenlight

@dasblinkenlight, 작업 세트의 성장은 무어의 법칙보다 문제에 더 이상 직교하지 않습니다. 작업 세트를 문제로 가져 오는 요점은 출시 시점에 간단한 솔루션에 약간의 성능 압박이 가해지면 작업 세트가 증가함에 따라 하드웨어 향상으로 인한 성능 향상이 철회되므로 가까운 시일 내에 성능이 충분하지 않다는 것입니다. 간단하고 신뢰할 수 있으며 유지 관리가 가능한 소프트웨어를 위해 모두 노력하고 있지만 이미 출시시 성능 압박을 받고있는 소프트웨어를 출시하고 무어의 법칙을 적용하는 것은 끔찍한 철학입니다.
user606723

3

간단한 솔루션으로 성능 SLA를 충족 할 수있는 경우 가장 최적의 복잡한 솔루션을 만드는 것이 좋은 방법입니까?

최적은 모호한 단어입니다!

궁극적으로, 복잡한 것을 유지해야 할 위험이 많고 단순한 것이 "충분히"좋은 경우에는 항상 단순한쪽에 오류가 있습니다.

복잡한 것이 충분하지 않을 위험이 있다면 KISS가 정답 일 것입니다.


2

나는 간단한 것을 선호합니다. 내 생각에 조기 최적화는 해결하는 것만 큼 많은 문제를 일으킨다. 대부분의 경우 좋은 디자인을 사용하면 병목 현상이 발생하면 향후 구현을 변경할 수 있습니다.

결론적으로, 가능한 한 유연하게 설계하지만 유연성을 위해 단순성을 희생하지는 않습니다.


2

어느 쪽이 더 저렴합니까?

대부분의 경우 약간 느린 느린 솔루션은 성능 측면에서 완벽하게 수용 가능하며 단순성으로 인해 개발, 유지 관리 및 교체 비용이 저렴합니다.

다른 한편으로, 때로는 속도가 정말로 중요하며, 작은 속도 향상으로 인한 재정적 이익은 더 복잡한 솔루션의 비용 증가보다 훨씬 클 수 있습니다. 예를 들어, 거래 완료 시간을 0.01 초로 줄이면 증권 거래 시스템의 수익성이 훨씬 높아질 수 있습니다. 수백만 명의 사용자를 지원하는 시스템의 효율성이 10 % 향상되면 서버 비용이 크게 절감 될 수 있습니다.

따라서 스스로 자문해야 할 질문은 다음과 같습니다. 복잡한 솔루션을 사용하면 추가 비용을 지불 할 수있는 수익성에 충분한 영향을 미칩니 까? 실제로 고객은 청구서를 지불하고 잠재적 이익을 거두기 때문에 고객에게 결정을 요청해야합니다. 한 가지 좋은 옵션은 간단한 솔루션을 먼저 사용하고 가능한 개선으로 더 복잡한 솔루션을 제공하는 것입니다. 이를 통해 시스템을 시작하고 실행할 수 있으며 클라이언트에게 테스트를 시작할 수있는 기회를 제공 할 수 있으며이 경험을 통해보다 복잡한 솔루션을 구현 (또는 구현하지 않음) 할 수 있습니다.


2

두 가지 접근 방식을 평가할 때 하나는 더 단순하지만 덜 효율적이고 다른 하나는 더 복잡하고 더 효율적입니다. 문제와 프로젝트 영역을 고려해야합니다.

15 년 이상의 유지 보수 및 +20 년의 수명을 계획 한 의료 산업을위한 수십억 개의 소프트웨어 프로젝트를 고려하십시오. 이러한 프로젝트의 성과는 분명히 문제가되지 않지만, 프로젝트 복잡성과 구조는 프로젝트 유지 보수에 중대한 문제를 야기 할 수 있으며, 이는 최소 15 년간 지속됩니다. 유지 보수성과 단순성이 무엇보다 중요합니다.

그런 다음 다른 예를 고려하십시오. 향후 5 년 동안 회사의 다가오는 게임을 지원할 콘솔 게임 엔진. 게임은 리소스 가 매우 제한된 프로그램 이기 때문에 대부분의 경우 효율성이 유지 관리 성보다 우선합니다. 소프트웨어 개발의 "우수 사례"에 위배되는 경우에도 일부 작업에 대해 고유 한 매우 구체적인 데이터 구조 및 알고리즘을 작성하는 것이 매우 중요 할 수 있습니다. 이에 대한 좋은 예는 실제 객체가 아닌 유사한 데이터 배열에 데이터를 저장하는 데이터 지향 설계 일 수 있습니다 . 이는 로컬 리티의 참조를 늘리고 CPU 캐시 효율성을 높이기위한 것입니다. 주어진 영역에서 실용적이지는 않지만 매우 중요합니다.


1

이것은 항상 어려운 질문이며 답변이 한 가지 방법으로 흔들리는 것을 보았습니다. 그래서 다른 쪽에서는 게임을 할 것입니다. 그러나 두 대답 중 어느 것이 맞는지 주장하지는 않지만 매우 부드럽고 사례별로 주제입니다.

복잡하지만 고성능 솔루션에 대한 한 가지 점은 항상 살아남은 문서를 문서화 할 수 있다는 것입니다. 나는 일반적으로 자체 문서화 코드의 팬이지만, 시간이 지나도 느려지지 않는 것처럼 느껴지는 소프트웨어 팬입니다. 복잡하지만 고성능 솔루션을 사용하는 경우 그렇게 나쁘지 않게 할 수있는 방법을 고려하십시오.

인터페이스로 감싸서 자체 어셈블리에 배치하십시오. 아마도 자체 프로세스 일 수도 있습니다. 누출 을 피하기 위해 가능한 한 두껍고 추상적 인 벽을 통해 가능한 한 느슨하게 결합하십시오 . 나중에 회귀를 저장하기 위해 많은 단위 테스트를 작성하십시오.

코드로 문서화하고 실제 문서 작성을 고려하십시오. 복잡한 데이터 구조와 문서화 방법에 대해 생각해보고, 데이터 구조 서적 / 위키피디아 기사가없는 코드에서 그 중 하나의 구현을 이해하려고 노력한다고 상상해보십시오. 그럼에도 불구하고 우리 모두는 이러한 복잡한 데이터 구조가 실제로 좋은 일임을 인정하고 누군가가 우리의 언어로이를 구현 한 것이 유리합니다.

우리 모두가 TCP / IP 스택을 통해 메시지를 전송한다는 것을 기억하십시오. 우리 중 누군가가 그것을 보았을 때 코드가 얻을 수있는 것처럼 해리가 생길 수 있습니다. 아마도 당신의 문제는이 수준의 최적화를 요구하지 않을 수도 있지만, 아마도 우리가 때때로해야 할 것처럼이 질문을 해결할 때주의하십시오. 용이 있습니다.


0

성능 SLA가없는 영역에서이 작업을 수행하려고합니다. 컴퓨터 그래픽에서 오프라인 렌더러에 관해서는, 사용자에게 "만족스러운 성능"이 없습니다. 이미 최신 렌더러로도 클라우드와 렌더 팜에 컴퓨팅을 분산시키기 위해 막대한 금액을 지불하고 있기 때문입니다. 영화를위한 프로덕션 품질의 이미지 및 프레임 출력

그러나 효율성을 위해 유지 관리 성을 크게 저하시키는 솔루션이 실제로 끊임없이 변화하는 성능 요구 사항에 맞서 작동하고 있다고 수년간이 영역에서 일하고 있다고 말해야합니다. 주변 코드와 경쟁자가 서로 성능을 계속 능가 할 것으로 기대하는 상황에서 여러 해 동안 솔루션을 효과적으로 유지할 수 없다면 솔루션은 이미 노후화되고 있습니다. 도매 교체가 필요합니다.

코드를 더 빠르게 실행하는 방법으로 VTune과 같은 프로파일 러의 궁극적 인 목적을 보지 못했습니다. 그들의 궁극적 인 가치는 끊임없이 증가하는 성능 요구를 충족시키기 위해 생산성을 떨어 뜨리지 않도록하는 것입니다. 나는 절대적으로 다음 몇 가지 총 보이는 마이크로 최적화 프로파일을 적용해야하는 경우, (내가 상상하는 몇 가지 테스트 케이스가 아닌 실제 사용자의 경우에 대해 그것을 실행과 결합 할 수 중요한을), I 적용 확인합니다 같은 필연적으로 총-보고 이 솔루션이 실행 가능한 상태가되면 앞으로 몇 년 동안 다시 방문하고 유지 보수 및 조정하고 변경해야하므로 필연적으로 표시되는 상위 핫스팟에만 매우 신중하게 최적화해야합니다.

특히 최적화 된 솔루션에 더 많은 커플 링이 필요한 경우에는 사용을 꺼려합니다. 코드베이스의 가장 중요한 성능 영역에서 감당해야 할 가장 귀중한 지표 중 하나는 (일부 필요한 정보의 양을 최소화하는 것과 마찬가지로 직접 변경이 필요하지 않은 한 변경이 필요할 가능성을 최소화하는) 분리입니다. )는 이러한 중요한 영역이 변경 이유를 크게 배가시키기 때문입니다. 즉, 업무 수행에 필요한 정보가 적고 변화에 대한 이유가 적으며 변화에 대한 이유를 최소화하는 것은 실제로 지속적으로 변화해야하기 때문에 특정 초점 영역에서 생산성을 향상시키는 데 큰 부분을 차지합니다. 그렇지 않으면 1 년 안에 쓸모 없게 될 것입니다)

내가 찾은 가장 크고 가장 효과적인 솔루션은 효율성과 유지 관리 성 및 생산성이 서로 정반대가 아닌 솔루션입니다. 저에게 필요한 것은 이러한 개념을 가능한 한 조화롭게 만드는 것입니다.

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