어디에서 최적화합니까?


9

속도를 최적화 할 수있는 두 가지 영역이 있습니다.

  • 가장 많은 시간이 소비되는 곳
  • 가장 많이 부르는 코드

최적화를 시작하기 가장 좋은 곳은 어디입니까?

종종 가장 많이 호출되는 코드는 이미 낮은 실행 시간을 갖습니다. 느리고 덜 호출되는 영역을 최적화합니까, 더 빠르고 많이 사용되는 영역을 최적화하는 데 시간을 보내십니까?


고객 또는 서버가 가장 큰 불만을 제기하는지 여부에 따라 고객 또는 아키텍처에 가장 큰 영향을 미치는 응용 프로그램 영역을 최적화하십시오.
Andy

그것은 가치 방정식입니다-대답은 둘 중 하나 일 수 있습니다. 실제 분석이 없으면 최상의 아이디어에 대한 보상을 바탕으로 장과 함께합니다.
Nicole

둘 다. 스택에있는 코드의 상당 부분을 찾으십시오.
Mike Dunlavey가

답변:


4

95 %의 작은 효율성을 무시해야합니다. 먼저 올바르게 작동 한 다음 분석하십시오 ...

당신의 디자인.

높은 수준의 알고리즘을 선택하면 소프트웨어의 전체 성능에 큰 영향을 줄 수 있습니다. 간단한 선택은 프로그램 시작을 기다리는 20 분의 대기 시간과 빠른 응답 UI를 갖는 것의 차이를 의미 할 수 있습니다.

예를 들어, 3D 게임에서 : 장면 그래프에 간단한 평면 객체 목록으로 시작하면 상대적으로 적은 수의 객체에 대해 성능이 크게 저하됩니다. 그러나 대신 그리는 동안 볼륨 계층 (예 : octree 또는 BVH)과 트리의 컬 부분을 구현하면 성능이 크게 향상됩니다.

디자인이 올 바르면 다음 단계로 넘어갈 수 있습니다.

저수준 논리.

하위 수준 알고리즘도 큰 영향을 줄 수 있습니다. 예를 들어 이미지를 잘못된 순서로 읽는 경우 이미지 처리를 수행 할 때 지속적인 L2 캐시 미스가 발생하면 속도가 크게 저하됩니다. 작업 순서를 변경하면 성능이 10 배 향상 될 수 있습니다.

이 시점에서 프로그램 시간의 대부분이 소요되는 장소를 프로파일 링하고 찾아 제거 할 수있는 방법을 찾으십시오.


내가하고있는 프로그램이 정확합니다. 웹 서비스는 실행하는 데 30 ~ 1 분이 걸릴 수 있기 때문에 가능하면 더 빨리 만들고 싶습니다.
Michael K

1
@Michael :이 경우 일반적인 프로그램 실행을 분석하고 가장 느리게 실행되는 코드 섹션을 찾아 낼 수있는 프로파일 링 도구를 사용할 차례입니다. 이 도구를 사용하는 것이 좋습니다. 직감으로 일정량을 할 수 있지만 때로는 호출하는 API가 자신의 코드가 아닌 상당한 시간이 걸리는 경우가 있습니다. 이 경우, API를 조사하고 사용 가능한 다른 기능을 살펴 보거나 자신의 대체 기능을 작성해야 할 경우 ... 실제 성능 호그가 항상 성능 이 의심되는 것은 아닙니다 ...
FrustratedWithFormsDesigner

1
프로파일 링 도구가 있습니다. 나는 아직도 그것을 배우고 있으며 정보로 무엇을해야합니까. 저에게는 비교적 새로운 주제이며 매우 흥미 롭습니다.
Michael K

@ 마이클 : 좋습니다! 성공적인 성능 조정을 위해 최선을 다하고 있습니다. :)
FrustratedWithFormsDesigner

+1 : 이것은 제가 말하려고했던 것보다 훨씬 더 설득력이 있습니다.
도미니크 맥도넬

3

먼저 프로파일 러를 실행하여 코드가 시간을 소비하는 위치를 찾으십시오.

그런 다음 해당 위치를보고 최적화하기 쉬운 위치를 확인하십시오.

가장 큰 이익을 얻을 수있는 가장 쉬운 방법을 찾으십시오 (낮은 과일을 찾으십시오). 그것이 얼마나 중요한지에 대해 너무 걱정하지 마십시오. 쉬운 경우 수정하십시오. 합산됩니다. 25 개의 쉬운 수정 프로그램이 1 개의 큰 수정 프로그램보다 빠를 수 있으며 누적 효과가 더 클 수 있습니다. 어려운 경우, 나중에 우선 순위를 지정할 수 있도록 메모하거나 버그 보고서를 제출하십시오. 이 시점에서 "큰"또는 "작은"에 대해 너무 걱정하지 마십시오. 아주 적은 시간을 사용하는 기능에 도달 할 때까지 그냥하십시오. 이렇게하면 발견 한 다른 문제 중 가장 적은 시간 동안 가장 큰 이익을 얻을 수있는 방법에 대해 더 잘 이해할 수 있습니다.

수정 후 일종의 회귀 테스트로 수정 후 프로파일 링을 수행하여 성능 변경에 원하는 효과가 있는지 확인하십시오. 또한 기능이 손상되지 않도록 회귀 스위트를 실행하는 것을 잊지 마십시오. 때로는 성능이 좋지 않으면 해결 방법이 표시되고 성능을 수정하려고하면 기능이 작동하지 않습니다.

최적화 할 수 없지만 많은 시간을 사용하는 작은 기능은 여전히 ​​최적화 할 위치에 대한 힌트 일 수 있습니다. 왜 그 함수가 그렇게 많이 호출됩니까? 그다지 사용할 필요가없는 작은 함수를 호출하는 함수가 있습니까? 작업이 중복되거나 불필요한 작업이 수행되고 있습니까? 자주 호출해야 할 때까지 스택이 호출되는 시간을 찾아 비효율적 인 알고리즘으로 더 큰 함수를 찾으십시오.

추가를 위해 편집 : 오랜 시간이 걸리는 특정 기능이 있으므로 해당 특정 기능을 10 회 정도 실행하여 위의 단계를 수행하십시오.


2

말하기 어렵다. 이것은 실제로 tha 코드가하는 일에 달려 있습니다. 성능 테스트를 실행하고 성능 프로필을 얻은 후 다양한 영역에서 실제 소요 시간을 확인하십시오 . 일반화는 ... 일반화이며 프로젝트마다 다릅니다.

예를 들어, 가장 많이 호출되는 코드는 단순히 파일이나 콘솔에 로그인 할 수 있습니다. 이미 하나 또는 두 줄의 코드로 간단하게 만들 수 없다면 최적화하는 데는 아무런 의미가 없으며, 이와 같은 것을 최적화하려는 노력은 실제로 코딩하는 비용이 들지 않을 수도 있습니다. 최소 코드는 엄청나게 복잡한 기능에 사용되는 괴물 크기의 쿼리 일 수 있습니다. 이 기능은 전체 실행 실행 (간단한 로깅 문에 대한 대 10000)를 통해 100 번 전화를받을 수도 있지만 모든 통화 시간 20 초 걸린다면 그것은 아마도, 실행 의 그 위치를 최적화 시작해야합니까? 또는 다른 방법으로 큰 쿼리가 가장 많이 호출되고 로깅 문은 100 쿼리마다 하나씩 호출됩니다.

무슨 일이 벌어 질지 미리 알지 못한다면 보통 이런 종류의 일에 대해 걱정하지 않습니다 (성능 조정을 수행해야 할 때까지).


1

"우리"는 보통 허용 할 수없는 속도가 느린 경우 최적화가 필요할 때까지 최적화하지 않습니다.

그리고 이러한 필요성이 나타날 때 일반적으로 정확히 최적화를 요구하는 것에 대한 좋은 힌트를 제공합니다.

따라서 정답은 "의존합니다"입니다.


1

소수의 일반적인 실행에서 프로파일 러를 사용하고 얼마나 자주 또는 얼마나 자주 도착했는지에 관계없이 코드의 각 부분에서 소요 되는 총 시간 을 확인해야합니다. 이러한 부품을 최적화하면 항상 속도가 증가해야합니다.

구현 언어의 수준이 어느 정도인지에 따라 대부분의 캐시 누락을 일으키는 부분을 찾아야합니다. 호출 코드를 통합하면 여기에 도움이됩니다.


1

문제는 "가장 많이 쓰는 시간"이라는 문구가 모호하다는 것입니다.

"프로그램 카운터가 가장 자주 발견되는 곳"을 의미하는 경우 문자열 비교, 메모리 할당, 수학 라이브러리 함수에서 가장 많은 시간을 소비 한 프로그램을 보았습니다. 다시 말해, 일상적인 프로그래머가 절대 만져서는 안되는 기능입니다.

"프로그래머의 코드에서 많은 시간을 소비하는 명령문이 실행되는 곳"을 의미하는 경우 더 유용한 개념입니다.

"가장 많이 호출되는 코드"개념의 문제점은 걸리는 시간과 호출 시간 및 호출 당 소요 시간 (발신자 및 I / O 포함)의 곱이라는 것입니다. 걸리는 시간은 여러 자릿수에 따라 달라질 수 있으므로 호출 횟수는 문제의 정도를 알려주지 않습니다. 함수 A는 10 번 호출되고 0.1 초가 걸리는 반면, 함수 B는 1000 번 호출되고 마이크로 초가 걸릴 수 있습니다.

어디를보아야하는지 알려주 것은 한 줄의 코드가 시간을 소비 때마다 스택에있는 것 입니다. 예를 들어 코드 줄이 핫스팟이거나 라이브러리 함수에 대한 호출이거나 30 수준 호출 트리에서 20 번째 호출 인 경우 시간의 20 %를 담당하는 경우 그런 다음 스택 시간의 20 %에 해당합니다. 스택의 임의 시간 샘플은 각각 20 %의 확률로 스택을 표시합니다. 또한 I / O 중에 샘플을 채취 할 수 있으면 I / O를 설명하는 CPU가 표시되는데, 이는 CPU 사이클 낭비만큼이나 더 낭비가 될 수 있습니다.

그리고 이것은 호출 횟수와는 완전히 독립적입니다.


'매일 프로그래머는 절대 만지지 말아야한다'는 말은 닿지 않을 것입니까? 또한 스택을 샘플링하는 것은 실용적인 프로파일 링 방법입니까?
Michael K

@Michael : 예. 스택을 샘플링하는 것은 Zoom 과 같은 최신 프로파일 러가 기반으로하는 방법입니다 . 또한 완전히 수동으로 작동 합니다 .
Mike Dunlavey가

매우 흥미로운. 지금 공부하고 있어요!
Michael K

@Michael : 공동 책임이라는 법적 개념과 같습니다. 특정 시점에서, 명령에있는 PC에 대한 책임은 해당 명령뿐만 아니라 스택 위의 모든 호출에 대한 공동 책임입니다. 그들 중 하나를 제거하면 특정 상태로 들어가는 것을 막을 수 있습니다.
Mike Dunlavey

0

특별한 이유가없는 한 가장 많은 시간을 소비하는 위치를 최적화하십시오 (즉, 대부분의 시간이 사람이 실제로 5 분 또는 10 분 안에 완료하는지 신경 쓰지 않는 비동기 처리를 수행하는 데 소요됨). 자연스럽게 가장 많이 호출되는 코드는 실행 시간이 짧아도 수천 번 수행하면 총 경과 시간의 상대적으로 많은 부분을 차지하는 경향이 있습니다.


0

시간이 가장 많이 걸리는 코드 작업을해야합니다. 런타임의 몇 퍼센트 만 차지하는 코드를 개선하면 약간의 향상을 가져올 수 있습니다.

어떤 코드가 가장 많은 시간을 소비하는지 알 수 있도록 측정 했습니까?


0

예전에는 슈퍼 컴퓨터 벤더를 대상으로 벤치마킹 및 마케팅을했기 때문에 경쟁에서 속도를 늦추는 것이 가장 중요하지 않은 것이 었습니다. 이런 종류의 결과를 위해서는 좋은 알고리즘과 가장 CPU 집약적 인 부분이 효율적으로 피크를 실행할 수있는 데이터 구조의 조합을 사용해야했습니다. 즉, 가장 계산 집약적 인 작업이 무엇인지, 그리고 어떤 종류의 데이터 구조가 가장 빠르게 실행될 수 있는지에 대한 좋은 아이디어를 가져야했습니다. 그런 다음 최적화 된 커널 / 데이터 구조를 중심으로 응용 프로그램을 구축해야했습니다.

좀 더 일반적인 의미에서, 사실 조정 이후의 일반적인 것입니다. 당신은 프로파일 링하고, 핫스팟을보고, 당신이 속도를 올릴 수 있다고 생각하는 핫스팟은 당신이 작업하는 것입니다. 그러나이 방법으로 가장 빠른 구현에 가까운 것은 거의 없습니다.

보다 일반적으로 (알고리즘 실수는 견딜 수 없음) 최신 기계의 경우 성능은 데이터 액세스, 데이터 액세스 및 데이터 액세스의 세 가지 요소에 의해 결정된다고 생각해야합니다! 메모리 계층 (레지스터, 캐시, TLB, 페이지 등)에 대해 배우고 가능한 한 잘 활용할 수 있도록 데이터 구조를 설계하십시오. 일반적으로 이는 컴팩트 메모리 풋 프린트 내에서 루프를 실행할 수있게하려는 것을 의미합니다. 대신 응용 프로그램을 작성 (또는 제공) 한 다음 최적화하려고하면 일반적으로 메모리 계층 구조를 제대로 사용하지 않는 데이터 구조로 구성되며 데이터 구조를 변경하면 일반적으로 주요 리팩터링 운동이 필요합니다. 종종 붙어.


0

최적화 노력에 대한 수익을 원한다면 가장 많은 시간이 걸리는 코드를 봐야합니다. 나의 일반적인 목표는 적어도 80 %의 시간이 걸리는 것입니다. 나는 일반적으로 10 배의 성능 향상을 목표로합니다. 때로는 코드 디자인 방식에 큰 변화가 필요합니다. 이런 종류의 변화는 대략 4 배 더 빠르게 실행되는 것을 얻습니다.

내 최고의 성능 향상은 실행 시간을 3 일에서 9 분으로 줄이는 것입니다. 내가 최적화 한 코드는 3 일에서 3 분으로 진행되었습니다. 대체 된 응용 프로그램은이 응용 프로그램을 9 초로 줄 였지만 언어를 변경하고 완전히 다시 작성해야했습니다.

이미 빠른 응용 프로그램을 최적화하는 것은 어리석은 일이 될 수 있습니다. 여전히 시간이 가장 많이 걸리는 지역을 타겟팅합니다. 10 %의 시간을 사용하여 즉시 돌아 오는 데 시간이 걸리더라도 90 %의 시간이 필요합니다. 수익이 감소하는 규칙에 빠르게 부딪칩니다.

규칙에 대해 최적화하는 내용에 따라 여전히 적용됩니다. 주요 자원 사용자를 찾아서 최적화하십시오. 최적화하려는 리소스가 시스템 병목 현상 인 경우 병목 현상을 다른 리소스로 변경하기 만하면됩니다.


0

일반적으로 루프에서 가장 자주 10 억 번 호출되는 기능이 아니라 대부분의 경우 더 강력한 기능이됩니다.

도구를 사용하거나 손으로 샘플 기반 프로파일 링을 수행 할 때 가장 큰 핫스팟은 종종 두 개의 정수를 비교하는 함수와 같이 간단한 작업을 수행하는 작은 잎이 많은 호출입니다.

이 기능은 종종 많은 최적화의 이점을 얻지 못합니다. 최소한 세분화 된 핫스팟이 최우선 순위는 아닙니다. 문제를 일으킬 수있는 리프 함수를 호출하는 함수이거나, 차선의 정렬 알고리즘과 같이 함수를 호출하는 함수를 호출하는 함수입니다. 좋은 도구를 사용하면 수신자에서 발신자로 드릴 다운하고 수신자에게 가장 많은 시간을 보낸 사람을 확인할 수 있습니다.

마이크로 레벨에서 매우 비효율적으로 작업을 수행하지 않는 한, 발신자에게 집착하고 프로파일 링 세션에서 발신자를 내려다 보지 않는 것은 종종 실수입니다. 그렇지 않으면 작은 물건을 과도하게 땀이 나고 큰 그림이 보이지 않을 수 있습니다. 프로파일 러를 가지고 있다고해서 사소한 일에 집착하는 것을 막을 수는 없습니다. 올바른 방향으로의 첫 걸음 일뿐입니다.

또한 사용자가 실제로하고 싶은 것과 일치하는 작업을 프로파일 링하고 있는지 확인해야합니다. 그렇지 않으면 고객이 제품과 수행하는 것과 일치하지 않기 때문에 측정 및 벤치 마크에서 완전히 훈련되고 과학적인 것이 가치가 없습니다. 한 번은 동료에게 하위 분할 알고리즘을 사용하여 큐브를 10 억 패싯으로 세분화하고 그에 많은 자부심을 가졌습니다. 사용자는 단순한 6 다각형 큐브를 10 억으로 세분화하지 않습니다. 패싯. 세분화를 위해 100,000 개가 넘는 다각형이있는 프로덕션 자동차 모델에서 실행하려고 할 때 크롤링 속도를 늦추지 않으면 서 2 ~ 3 단계의 세분화조차 할 수 없었습니다. 간단히 말해서 그는 비현실적으로 작은 입력 크기에 최적화 된 코드를 작성했습니다.

코드의 유지 관리 성을 다소 저하시키는 경향이있는 모든 최적화에는 사용자 이익이 거의없고 코드베이스에 대한 모든 부정적인 점만 있기 때문에 사용자의 관심사에 맞춰 실제 사용 사례를 최적화해야합니다.

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