“개발자의 나쁜 최적화 직관”을 피하려면 어떻게해야합니까?


22

나는 이 진술 을하는 기사 를 보았다 :

개발자는 코드를 최적화하는 데 합당한 이유가 있습니다. 너무 만족스럽고 재미 있습니다. 그러나 언제 최적화해야하는지 아는 것이 훨씬 중요합니다. 불행히도 개발자는 일반적으로 응용 프로그램의 성능 문제가 실제로 어디에 있는지에 대한 끔찍한 직감을 가지고 있습니다.

개발자가이 나쁜 직감을 피할 수있는 방법은 무엇입니까? 코드에서 어떤 부분이 실제로 최적화가 필요한지를 찾는 좋은 도구가 있습니까 (Java 용)? 이 주제에 관한 기사, 팁 또는 좋은 기사를 알고 있습니까?


1
이것은 "내가 결정을 내릴 때 직관에 의존하는 것을 피하는 방법"으로 귀결됩니다. 간단 함 : 확실한 사실과 데이터로 확인합니다. 따라서 최적화의 경우 개발자의 관점에서 벤치마킹하십시오.
haylem

답변:


44
  • 좋은 프로파일 러를 사용하여 비싼 방법을 식별하십시오.
  • 핫스팟이 실제로 걸린 시간을 기록하십시오.
  • 핫스팟의 빠른 구현 작성
  • 핫스팟이 더 이상 핫스팟으로 만들어지지 않기를 바랍니다.

본질적으로 문제가 있었던 다른 사람들에게 증명할 수 있어야하며,이 변경으로 인해 문제가 해결되었습니다.

개선 사항 을 입증 할 수 없어서 개인적으로는 원래 버전으로 즉시 롤백 할 수 있습니다.


51
또는 더 간단하게 말하면 : "최적화 직관을 피하기 위해 직관을 사용하지 마십시오. 측정"
Kyralessa

6
그렇기 때문에 당신이 대답하고 내 의견 일뿐입니다. : P
Kyralessa

2
@Thomas, 가독성과 유지 관리 능력이 뛰어나면 성능 문제를 정확히보고 있지 않습니까?

3
@ 토마스, 동의하지 않습니다. 사양 내에서도 새 코드를 철저히 다시 테스트해야합니다. 이전 코드에는 필요하지 않습니다. 돌아가다.

2
@ Thorbjørn 성능 조정 후 새 코드를 철저히 다시 테스트해야합니다. 결함이 발생한 경우 시간이나 메모리를 절약하는 것은 의미가 없습니다.
토마스 오웬스

10

최적화 할 위치를 알 수있는 유일한 방법은 코드를 프로파일 링하는 것입니다. 이점을 제공 할 것으로 생각되는 변경을 수행하는 대신 가장 성능이 좋지 않은 코드의 위치를 ​​알고 시작하십시오.

Java는 최신 릴리스의 Java Development Kit (JDK)와 함께 제공되는 VisualVM 도구를 사용하여이 작업을 쉽게 수행 할 수 있습니다. 아이디어는 코드와 외부 라이브러리에서 가장 많이 호출되는 메소드와 가장 많은 시간을 소비하는 메소드를 찾는 것입니다. 가비지 수집에 대한 성능 데이터를 얻을 수 있으므로 수집기를 조정하고 응용 프로그램에 필요한 최소 / 최대 힙 공간을 조정할 수 있습니다.


VisualVM은 JRE가 아니라 JDK에만 있습니다.

1
@ Thorbjørn Ravn Andersen 안녕하세요. 명확히해야합니다. 그러나 Java 개발을하는 경우 일반적으로 JDK가 설치되어 있습니다 (OpenJDK 또는 이와 유사한 것을 실행 중일 수도 있지만 VisualVM과 함께 제공되는지 여부는 알 수 없습니다).
Thomas Owens

1
Eclipse에서 작업 공간을 자주 전환 한 다음 Eclipse를 시작한 JRE로 기본 설정합니다. JDK보다 JRE를 설치하는 것이 훨씬 쉽기 때문에 Eclipse 컴파일러를 포함하는 개미 빌드 프로세스로 천천히 마이그레이션하여 일반 JRE에서 실행할 수 있습니다. 따라서 요즘 JDK없이 실제 작업을 수행 할 수 있습니다 . Windows 64 비트 JVM에서는 32 비트 JVM에 연결할 수없고 그 반대도 가능하므로 VisualVM을 별도로 다운로드하여 지정된 Java 버전에서 더 쉽게 사용할 수 있습니다.

9

여기 누구든지 프로파일 러 에 대해 이야기 할 때이 부분에 초점을 맞출 것입니다.

개발자가이 나쁜 직감을 피할 수있는 방법은 무엇입니까?

당신. 해야 할 것. 아니. 대신 초기에 최적화하지 마십시오 .
종교적 만트라이므로 반복해서 반복하십시오.

당신은 그렇게하고있는 것을 알게 될 것이며, 그렇게하지 말아야 할 것을 발견 할 것입니다.
그리고 다시.
그리고 다시.

조기 최적화 는 프로그래머의 자본 죄 중 하나입니다 .

도구 및 물건의 일부 나중에 최적화 입니다 설립 공예 .


초기 "복잡한 코드"최적화. 문제에 적합하고 (예상 처리로드와 함께) 우수한 성능 특성을 갖는 Chjoosing 알고리즘 및 / 또는 데이터 구조는 코드 작성을 시작하기 전에 수행해야합니다.
Vatine

@Vatine 예, 거기있었습니다. 아뇨. 당면한 문제에 대한 당신의 마인드 맵에 맞는 것을하십시오. 그것은 가장 성능이 좋은 알고리즘 있으며 , 필요하지 않기를 바랍니다.
ZJR

그것은 YAGNI 원리로 나에게 들린다 – 당신은 그것을 필요로하지 않을 것이다!
EL Yusubov

7

이러한 도구를 프로파일 러 라고 합니다. 이를 사용하여 실제로 프로그램 실행에 가장 많은 시간이 걸리는 부분을 측정하여 튜닝 노력에 집중할 수 있습니다.

변경 후에 의도 한 효과가 있는지 확인하기 위해 변경 후에 다시 측정하는 것도 중요합니다 .


5

속도 나 런타임뿐만 아니라 프로그램이 사용하는 메모리 양도 살펴보십시오.

Java와 같은 가비지 수집 언어로 작업하는 많은 코더는 가비지 수집으로 인해 메모리 누수가 방지된다는 잘못된 생각에 처해 있습니다. 그렇지 않습니다. 더 이상 필요하지 않은 객체에 대한 참조를 보유하면 수집되지 않으므로 누출됩니다.

Java 웹 응용 프로그램이 너무 유출되어 스왑 공간에서 서버를 실행하는 것을 보았습니다!

런타임 프로파일 러와 일부 방식의 메모리 프로파일 러를 모두 사용하는 경우보다 빠르고 간결한 코드를 직관적으로 작성하는 방법을 배우게됩니다. 이는 첫 번째 시도에서 코드가 더 빨리 실행될 가능성이 있습니다.


1

내 치료법은 두 가지 질문에 대한 명확한 대답을 얻는 것부터 시작하는 것입니다.

  1. 성능 측정 방법 (예 : 데이터로드 시간 측정 )
  2. 목표 값은 얼마입니까 (예 : 95 % 신뢰도로 3 초 이내에 데이터로드 )

한때 우리 제품의 깨진 릴리스를 저장하도록 초대받은 호랑이 팀 사람들 로부터 위의 트릭을 배웠습니다 . 이 릴리스는 성능상의 이유로 중단되었으므로 회사가 전략적 고객을 느슨하게 만들 수 있었으며 이는 타이거 사람들의 참여 를 정당화 할 수있었습니다 (꽤 비싼 btw). 나는 그들이 프로젝트 세부 사항을 명확히하는 것을 돕기 위해 지명되었다. 또한 성능에 대해 약간 또는 두 가지를 배울 수있는 기회로 사용했습니다.


1

내가 발견 한 것은 조기 최적화에 가장 좋은 해독제입니다 이 방법 .

이 예제 에서와 같이 일부 코드의 속도를 높이기 위해이 코드를 사용하면 자체 중독이되고 성능 조정의 첫 번째 원칙이 코드를 조정하지 않는다는 것을 이해 하면 문제가 발생하는 것 입니다.

실제 최적화는 가족에게 먹이를주는 사냥이 깡통을 쏘는 것이므로 조기 최적화하는 것입니다. 채석장을 찾는 것이 전부입니다.


1
불행히도, 당신은 가족에게 200 파운드를 돌려 줄 수 있기 때문에 하루 종일 다람쥐를 쏘지 마십시오.
Jordan

1

오래된 질문이지만 다른 답변과 상당히 다른이 답변을 제공 할 것입니다.

성능 향상의 큰 기회는 병렬 처리에서 비롯됩니다. 여러 스레드를 활용하도록 코드를 설계하십시오. (단순화를 위해 버전 1에서는 그렇게하지 않더라도). 작은 추측이나 직관이 필요합니다.

다른 것은 조기 최적화이며 직관이 필요하며 종종 잘못된 것입니다.


정말 좋은 지적입니다. 과거에는 몇 년마다 프로세서 속도가 훨씬 빨라질 수있었습니다. 이제 더 많은 프로세서가있을 것으로 기대합니다.
JimmyJames

0

시간이 지남에 따라 직감 향상 될 수 있습니다 . 나는 약간 논란의 여지가 있지만, VTune과 CodeAnalyst를 사용하고 현재 CodeXL을 사용하면서 수년 동안 핫스팟이 어디에 있는지에 대해 직관보다 훨씬 정확하다고 말했습니다. 일부 코드를 프로파일 링 할 때 더 이상 완벽하게 보호되지 않는 지점. 그렇다고 맹목적으로 최적화하려고 시도하는 것은 아닙니다.

프로파일 링은 실제로 프로파일 러에 대한 의존도를 높이는 것이 아니라 줄였습니다. 필자는 프로파일 링 결과가 어느 정도 더 쉽게 예측 될 수 있는지, 핫스팟을 성공적으로 제거하고 어둠 속에서 길을 잃지 않고 사용자 엔드 작업을 완료하는 데 걸리는 시간을 단축 할 수 있다고 말합니다. 핫스팟이 무엇인지뿐만 아니라 캐시 미스와 관련하여 핫스팟이 왜 정확한지 이해하기 시작할 때까지 프로파일 러를 사용할 때도 가능합니다.

그러나 프로파일 러를 사용하기 전에는 직관력을 향상시키기 시작했습니다. 그 이유 중 하나는 코드에 익숙한 경우 가장 크고 가장 명백한 핫스팟과 관련하여 사용자의 직감이 정확할 수 있지만 그 사이의 모든 미묘한 것은 아닙니다. 당연히 완료하는 데 1 시간이 걸리는 사용자 엔드 작업이 있고 수십만 개의 요소에 걸친 입력을 처리하는 격차 이차 복잡성 알고리즘이 있다면, 아마도 이차 복잡성이라는 생각으로 전체 생명을 구할 수있는 풍부한 도박을 할 수있을 것입니다 여기서 오류 알고리즘. 그러나 그것은 당신에게 자세한 통찰력을 제공하지 않거나 , 시간에 기여 하지 않는 것을 정확하게 알려주지 않습니다 .

프로파일 링을 시작하고 시간을 크게 기여한 것으로 생각 된 모든 것들이 많은 시간을 기여하지 않는 곳을 볼 때 많은 가치가 있습니다. 비효율적 인 명백한 비 효율성의 원인이 아니라 의심되는 것들이 약간 비효율적이었을 수도 있지만 프로파일 링 후에는 시간이 거의 걸리지 않았다는 것을 깨달았습니다. 그리고 그것이 가장 직관적 인 통찰력을 얻는 곳은 잠재적으로 얼마나 많은 시간을 소비하고 있는지 명확하지 않은 모든 미묘한 영역에서 자신이 잘못되고 있음을 발견하는 것입니다.

명백한 알고리즘 복잡성 이상의 인간 직관은 종종 기계에 효율적인 것과 인간의 마음에 효율적인 것이 매우 다르기 때문에 잘못된 것으로 시작합니다. 처음에는 레지스터에서 CPU 캐시로, DRAM에서 디스크로가는 메모리 계층 구조에 대해 생각하는 것이 직관적이지 않습니다. 일부 처리 작업을 건너 뛰기 위해 룩업 테이블의 더 많은 분기 또는 메모리 액세스를 수행하는 것보다 중복 산술이 더 빠르다고 생각하는 것은 직관적으로 오지 않습니다. 의사 결정 비용, 메모리로드 및 저장 비용 등을 할인하면서 수행해야하는 작업량을 고려하는 경향이 있습니다. 하드웨어에 효율적인 것은 인간의 모든 가정을 시작하는 방식으로 반 직관적 일 수 있습니다.

프로파일 링을 통해 직관을 향상시키는 데 도움이되는 부분은 인터페이스 디자인 입니다. 인터페이스 디자인은 후시로 변경하는 데 비용이 많이 들고, 인터페이스에 따라 장소 수에 비례하여 비용이 증가합니다. 직관력 향상을 시작하면 비용이 많이 드는 설계 변경없이 향후 최적화를위한 호흡 공간을 남겨 두는 방식으로 인터페이스를 처음으로 더 잘 설계 할 수 있습니다. 다시 말하지만, 직관은 일반적으로 당신이 일반적으로 개발하고 항상 그 프로파일 러를 손에 둠으로써 무한정으로 발전하는 것입니다.


0

프로파일 러는 코드와 관련하여 잘못된 직감을 수정하는 데 도움이됩니다. 요즘 하드웨어가 얼마나 많은 양을 예측 하는지를 감안할 때 코드 성능을 예측하는 것은 인간적으로 실용적이지는 않지만 수십 년 전 Knuth 시대에도 여전히 사실이었습니다. 누가 프로파일 러를 수정하기 위해 표준 도구의 일부로 프로파일 러를 포함시켜야한다고 주장 개발자의 "페니와 파운드 어리석은"본질. 그러나 답변이 다른 측면에서 얼마나 포괄적이고 사용자 엔드 이해가 다른 "수정"이라고 말하면이 답변과는 매우 다른 경로를 밟을 것입니다.

필자는 개인 경험에서 특히 뛰어난 개발자 (그러나 사용자가 실제로 소프트웨어를 사용하는 방법에 대한 맹점을 가지고 있음)를보고 프로파일 러를 사용하여 세분화 알고리즘을 최적화 (매우 훌륭하고 비싸고 포괄적 인 것 : 콜 그래프가있는 Intel의 VTune) 6 개의 케이지 / 입력 폴리곤이있는 큐브와 같은 간단한 프리미티브를 세분화 할 때 GPU에서 수십억 개의 패싯으로 놀라운 결과를 얻을 수 있습니다. 실제 사용 사례와 달리 테스트 사례에 맞게 조정하고 조정 한 경우를 제외하고 (사용자는 완전한 구를 닮기 시작하는 하위 분할 큐브에 10 억 개의 패싯을 원하지 않음) 하위 분할 입력은 문자 및 차량과 같은 경향이 있습니다. 다른 복잡한 입력).

재미있게도 나는 사용자의 요구, 마케팅, 디자이너가 원하는 것을 이해 한 단순한 이유 때문에 그와 같은 기능을 할 수있는 두뇌의 절반을 더 많이 얻었고 내 경력에 대해 박사 학위를받지 못했습니다. 나는 사용자의 사고 방식과 신발에 자신을 넣고 소프트웨어를 살펴보고 실제 사용자가해야 할 일을 당신이 넣은 노력과 이혼하려고 노력하면서 얼마나 유용한 지 실제로 강조 할 수는 없습니다. 당신이 짓은 것을 만들고 신선한 눈으로보고 있습니다. 나는 심지어 불가능한 일이라는 것을 개발자로부터 만났다. 그는 기술적으로 능숙하지만 사용자가 모르는 모든 개발자가 갖고있는 비슷한 종류의 자아가 유죄라고 생각했으며, 사용자와 디자이너가 정확히 무엇을해야하는지 이야기하기 위해 무리를 지을 때 그를 잘못 판단했습니다. 그것은 매우 이기적으로 들리지만, 나는 그런 훌륭한 코더가 아니라는 면책 조항과 균형을 잡을 것입니다. 어떤 이유로 품질. 프로그래머로서 우리는 평범하고 기술이 아닌 사람들을 이해하고 사교하는 것보다 테스트를하는 데 더 익숙 할 것입니다.

프로파일 링과 적절하게 측정 할 수 있지만 실제 사용자가 실제로 응용 프로그램에 제공 할 입력 유형으로 작업을 측정하고 있는지 확인해야하는 근본적인 필요성도 있습니다. 그렇지 않으면 VTune 또는 CodeAnalyst 또는 gprof 또는 기타 프로파일 러를 사용할 수 있으며 개발자에게는 일반적인 테스트 사례처럼 보일 수 있지만 사용자에게는 모호한 핫스팟을 최적화하려고 시도하는 동안 일반적인 사용 사례를 비판하게됩니다. 소수의 사용자가 있다면 적용을 고려하는 모호한 사용 사례를 선호합니다.

하루가 끝날 무렵, 우리는 개발자가 세계 기아를 해결하지 않고 사용자를 진정으로 행복하게 만드는 것의 철 망치와 균형을 잡을 수있는 경향이 있으며, 임대료를 지불하거나 맥주를 사거나 벌거 벗은 숙녀 또는 당신이 원하거나 필요로하는 것을보십시오. 그 밖의 모든 것은 잠재적 인 근본적인 비즈니스 요구에 부응하고 있으며, 모든 개발자는 돈을 벌고 궁극적으로 사용자가 돈을 지불하도록 만족시키는 것을 잊어 버리는 것을 잊어 버릴 수 있습니다. 가상 세계를 만드는 신 모드를 끄고 단순히 음식을 구하기 위해 돈을 벌어야하는 실제 세계에 유리합니다. 우리는 소프트웨어 지표와 관행에서 길을 잃을 수 있지만 기본적으로

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