모듈 식 프로그래밍이 계산 시간에 영향을 줍니까?


19

누구나 코드를 모듈화해야한다고 말하지만 더 적지 않지만 더 큰 메소드보다는 더 많은 메소드 호출을 사용하면 덜 효율적이지 않습니까? 그 문제에 대한 Java, C 또는 C ++의 차이점은 무엇입니까?

특히 그룹에서 편집, 읽기 및 이해하기가 더 쉽다는 것을 알게되었습니다. 따라서 코드 시간 이점과 비교할 때 계산 시간 손실이 중요하지 않습니까?


2
문제는 더 어려운 유지 보수에 소요되는 시간을 절약하는 처리 시간에 걸리는 시간입니다. 이에 대한 대답은 전적으로 응용 프로그램에 따라 다릅니다.
Blrfl

2
많은 좋은 질문은 전문가 경험을 바탕으로 어느 정도의 의견을 생성하지만이 질문에 대한 답변은 사실, 참조 또는 특정 전문 지식이 아닌 의견에 거의 근거한 경향이 있습니다.
gnat

10
함수 또는 메소드 호출에 대한 계산 페널티가 너무 작아서 많은 함수 및 메소드 호출이있는 매우 큰 프로그램 에서도
greyfade

1
@greyfade : 직접 점프의 경우에는 사실이지만 추가 간접 예측 점프는 예를 들어 프로그램의 총 실행 시간의 약 3 %가 소요될 수 있습니다 (최근에 확인한 프로그램의 수에 불과하지만 대표적이지 않았을 수도 있음). 지역에 따라 중요하거나 고려하지 않을 수도 있지만 차트에 등록했습니다 (물론 모듈화에 적어도 부분적으로 직교합니다).
Maciej Piechotka

4
조기 최적화는 모든 악의 근원입니다. 선형 코드는 모듈 식 코드보다 약간 빠릅니다. 모듈 식 코드는 스파게티 코드보다 훨씬 빠릅니다. 전체적으로 매우 (매우) 철저한 프로젝트없이 선형 코드를 목표로한다면 스파게티 코드로 끝날 것입니다.
SF.

답변:


46

그렇습니다.

컴퓨터는 두뇌와 비교할 수없는 속도로 작동하는 지칠 줄 모르고 거의 완벽한 실행 엔진입니다. 함수 호출이 프로그램의 실행 시간에 추가되는 상당한 시간이 있지만, 읽을 수없는 루틴을 풀어야 할 때 코드와 관련된 다음 사람의 두뇌에 필요한 추가 시간과 비교하면 아무것도 아닙니다 도에 시작 그것으로 작업하는 방법을 이해합니다. 농담에 대한 계산을 시도 할 수 있습니다. 코드를 한 번만 유지해야한다고 가정하고 누군가 코드를 이해하는 데 필요한 시간을 30 분만 추가 하면 됩니다 . 프로세서 클럭 속도를 계산하고 계산하십시오. 오프셋을 꿈꾸 려면 몇 번이나 코드를 실행 해야합니까?

요컨대, CPU를 불쌍히 여기는 것은 시간의 99.99 %를 완전히 잘못 인도 한 것입니다. 드문 경우로 프로파일 러를 사용하십시오. 마십시오 하지 당신이 그 사례를 발견 할 수 있다고 가정 - 당신은 할 수 없습니다.


2
나는 그것이 대부분 조기 최적화에 동의하지만, 시간에 대한 당신의 주장은 나쁘다고 생각합니다. 시간은 다른 상황에서 상대적이며 당신이 한 것처럼 단순히 계산할 수 없습니다.
Honza Brabec

28
"CPU에서 동정을 취하는 것"이라는 표현은 +1인데, 이는 조기 최적화에서 잘못된 방향을 강조하기 때문입니다.
Michael Borgwardt

4
관련성이 높음 : 컴퓨터는 일상적으로 얼마나 빠릅니까? "속도"에 대한 몇 가지 함수 호출을 피하기 위해 길을 떠나는 것은 평생 동안 총 1 분 동안 누군가를 구하는 길을 떠나는 것과 같습니다 . 한마디로 : 고려할 시간조차도 가치가 없습니다.
BlueRaja-대니 Pflughoeft

7
많은 사람들이 잃어버린 것을 웅변 적으로 팔아서 +1하지만, CPU를 더 불쌍하게 만드는 균형에 가장 중요한 무게를 더하는 것을 잊었습니다. 한 번 유지 보수에 소비 된 돈과 시간을 무시하고; 1 초가 걸린다면 여전히 훨씬 더 교활한 싱크대가 있습니다. 버그 위험 . 나중에 유지 보수 담당자가 코드를 변경하는 것이 더 혼란스럽고 어려울수록 버그를 구현할 위험이 커져 사용자에게 불가피하게 막대한 비용이 발생할 수 있으며 버그는 후속 유지 보수를 유발할 수 있습니다 (이로 인해 발생할 수 있음) bugs ...)
Jimmy Hoffa

저의 오래된 선생은 "너희가 조기에 최적화하고 있는지 아닌지를 생각하고 있다면 여기서 멈추십시오. 이것이 올바른 선택이라면, 당신은 그것을 알 것입니다."
Ven

22

때에 따라 다르지.

느리게 진행되는 웹 프로그래밍, 즉 모든 것이 사람의 속도로 발생하는 웹 프로그래밍, 메소드 호출 프로그래밍, 메소드 호출 비용이 메소드가 수행하는 처리 비용과 비슷하거나 초과하는 경우는 중요하지 않습니다. .

임베디드 시스템 프로그래밍 및 고속 인터럽트에 대한 인터럽트 핸들러의 세계에서 가장 중요합니다. 해당 환경에서 일반적인 "메모리 액세스는 저렴"하고 "프로세서는 무한정 빠릅니다"라는 분류가 있습니다. 메인 프레임 객체 지향 프로그래머가 첫 번째 고속 인터럽트 핸들러를 작성할 때 어떤 일이 발생하는지 보았습니다. 예쁘지 않았습니다.

몇 년 전, 나는 실시간 FLIR 이미지에서 비 재귀적인 8 방향 연결성 얼룩 색소를 수행했습니다. 당시에는 적절한 프로세서였습니다. 첫 번째 시도는 서브 루틴 호출을 사용했으며 서브 루틴 호출 오버 헤드는 프로세서를 활성 상태로 만들었습니다. (4 호출 PER PIXEL x 프레임 당 64K 픽셀 x 초당 30 프레임 = 계산). 두 번째 시도는 서브 루틴을 가독성 손실없이 C 매크로로 변경했으며 모든 것이 장미였습니다.

당신은 당신이하고있는 일과 그것을 할 환경을 열심히 봐야합니다.


현대 프로그래밍 문제의 대부분은 많은 객체 지향, 메소드-행복한 코드를 처리하는 것이 가장 좋습니다. 임베디드 시스템 환경에있을 때 알게됩니다.
Kevin-복원 모니카

4
+1이지만주의 사항 : 일반적으로 최적화 컴파일러가 사람보다 인라인, 루프 언 롤링 및 스칼라 및 벡터 최적화 작업을 더 잘 수행하는 경우가 많습니다. 프로그래머는 여전히 언어, 컴파일러 및 기계를 잘 알고 있어야 이것을 활용할 수 있으므로 마술이 아닙니다.
detly

2
사실이지만 로직을 작성하고 프로파일 링 한 후 알고리즘에서 문제가있는 부분을 찾도록 코드를 최적화 했습니다. 성능을 위해 코딩하기 시작하지 않았지만 가독성을 위해 코딩을 시작했습니다. 매크로는 코드를 읽을 수있게 유지하는 데 도움이됩니다.
Uwe Plonus

2
임베디드 시스템 프로그래밍도에 분명 올바른 코드를 작성하여 시작하고 해당 후 최적화 시작 필요한 경우프로파일에 의해 인도로 . 그렇지 않으면 성능 / 코드 크기에 실제로 영향을 미치지 않고 소스를 이해하기 어렵게 만드는 많은 작업을 수행하기가 너무 쉽습니다.
Donal Fellows

1
@detly : 그렇습니다. 현대의 컴파일러는 일반적으로 언어가 부과하는 한계 내에서 더 나은 작업을 수행 할 수 있습니다. 인간 프로그래머는 언어에 의해 부과 된 한계가 특정 상황에 적용 가능한지 여부를 알고 있습니다. 예를 들어, Cn 및 C ++ 컴파일러는 언어 표준에 따라 프로그래머가 매우 병적 인 일을하고 어쨌든 작동하는 코드를 생성 할 수 있도록 요구합니다. 프로그래머는 자신이 그런 일을하기에 충분히 미쳤거나 어리 석거나 모험적이지 않다는 것을 알 수 있으며,이 경우 안전하다는 것을 알고 있기 때문에 안전하지 않은 최적화를 수행 할 수 있습니다.
John R. Strohm

11

우선 : 더 높은 언어의 프로그램은 기계가 아닌 사람이 읽을 수 있습니다.

그래서 그래서 프로그램을 작성하는 당신 을 이해합니다. 성능에 대해 생각하지 마십시오 (성능 문제가 심각하면 응용 프로그램을 프로파일 링하고 필요한 경우 성능을 향상 시키십시오).

메서드 나 함수를 호출하는 데 약간의 오버 헤드가 걸린다는 것은 사실이 중요하지 않습니다. 오늘날 컴파일러는 생성 된 코드가 대상 아키텍처에 효율적이되도록 효율적인 코드로 코드를 컴파일 할 수 있어야합니다. 효율적인 코드를 얻으려면 컴파일러의 최적화 스위치를 사용하십시오.


5
다른 사람들 이 이해할 수 있는 방식으로 프로그램을 작성해야한다고 말하고 싶습니다 .
Bartlomiej Lewandowski

프로그램을 읽어야하는 첫 번째 사람은 개발자 자신입니다. 그게 내가 당신을 쓴 이유 입니다. 다른 사람이 프로그램을 읽을 수 있다면 좋지만 (내 눈에는) 필요하지 않습니다 (처음에는). 팀에서 일하는 경우 다른 사람도 프로그램을 이해해야하지만 내 의도는 사람이 컴퓨터가 아닌 프로그램을 읽어야한다는 것입니다.
Uwe Plonus

5

일반적으로 큰 기능을 가지고 있고 더 작은 기능으로 나눌 때이 작은 기능은 인라인 의 유일한 단점 (동일한 명령을 너무 많이 반복)이 관련이 없기 때문에 인라인 됩니다. 즉, 코드가 하나의 큰 함수를 작성한 것처럼 작동합니다.

어떤 이유로 인라인되지 않았고 이것이 성능 문제가되는 경우 수동 인라인을 고려해야합니다. 모든 응용 프로그램이 내재 된 대기 시간이 큰 네트워크 CRUD 양식은 아닙니다.


2

계산 비용이 없을 것입니다. 일반적으로 지난 10-20 년 동안의 컴파일러 / JIT는 완벽하게 미세한 함수를 처리합니다. C / C ++의 경우 일반적으로 'inlinable'함수로 제한됩니다 (즉, 함수 정의는 컴파일하는 동안 컴파일러에서 사용할 수 있습니다. 즉, 동일한 파일의 헤더에 있음). LTO의 현재 기술은이를 극복합니다.

최적화에 시간을 소비해야하는 경우 작업중인 영역에 따라 다릅니다. 입력을 기다리는 대부분의 시간을 소비 한 '정상적인'응용 프로그램을 처리하는 경우 응용 프로그램이 '느낌'을 느끼지 않으면 최적화에 대해 걱정할 필요가 없습니다.

이러한 경우에도 미세 최적화를 수행하기 전에 많은 것에 집중해야합니다.

  • 문제는 어디에 있습니까? 소스 코드를 다르게 읽는 사람들은 일반적으로 핫스팟을 찾기가 어렵습니다. 우리는 작동 시간의 비율이 다르며 최신 프로세서 는 그렇지 않지만 순차적으로 수행합니다 .
  • 매번 계산이 필요합니까? 예를 들어, 수천 개 중 하나의 매개 변수를 변경하면 전체 모델 대신 영향을받는 부분 만 계산할 수 있습니다.
  • 최적의 알고리즘을 사용합니까? 에서 O(n)로 변경 O(log n)하면 미세 최적화를 통해 달성 할 수있는 것보다 훨씬 큰 영향을 줄 수 있습니다.
  • 적절한 구조를 사용하십니까? 당신은을 사용하는 말 List당신이 필요로 할 때 HashSet당신은 그래서 O(n)조회를 당신이 가진 수있을 때 O(1).
  • 병렬 처리를 효율적으로 사용합니까? 현재 휴대폰조차도 4 코어 이상을 가질 수 있으며 스레드 사용을 유혹 할 수도 있습니다. 그러나 동기화 비용이 들기 때문에 은총 알이 아닙니다 (문제가 메모리 바운드 인 경우 어쨌든 의미가 없음).

(소프트웨어가, HPC에 사용되는 내장하거나에서 사용되는 거의 수단 심지어 당신이 마이크로 최적화를 수행 할 필요가 있다고 결정했다면 매우 당신이 필요합니다 - 그렇지 않으면 유지 보수의 추가 비용이 컴퓨터 시간 비용을 극복하는 사람들의 많은 수의) 가속화하려는 핫스팟 (커널)을 식별합니다. 그러나 아마 당신은해야합니다 :

  1. 작업중인 플랫폼을 정확히 파악
  2. 작업중인 컴파일러와 수행 할 수있는 최적화 및 이러한 최적화를 가능하게하는 관용적 코드 작성 방법을 정확히 알고 있어야합니다.
  3. 메모리 액세스 패턴과 캐시에 얼마나 많은 양을 넣을 수 있는지 생각하십시오 (정확한 크기는 1 지점에서 알고 있음).
  4. 그런 다음 계산 바운드 인 경우 계산을 저장하기 위해 계산 재구성에 대해 생각하십시오.

마지막 말로. 일반적으로 메서드 호출과 관련된 유일한 문제는 분기 예측기에 의해 예측되지 않은 간접 점프 (가상 메서드)입니다 (불행히도 간접 점프는 어려운 경우입니다). 하나:

  • Java에는 많은 경우 클래스 유형을 예측할 수있는 JIT가 있으므로 사전에 점프 대상을 지정하므로 핫스팟에서는 많은 문제가 발생하지 않습니다.
  • C ++ 컴파일러는 종종 프로그램 분석을 수행하며 최소한 경우에 따라 컴파일 타임에 대상을 예측할 수 있습니다.
  • 두 경우 모두 목표가 예측 된 경우 인라인이 작동해야합니다. 컴파일러가 인라인 기회를 수행 할 수 없다면 우리도 할 수 없었습니다.

0

내 대답은 기존 답변에서 너무 많이 확장되지는 않지만 2 센트가 도움이 될 것 같습니다.

우선; 예, 모듈화의 경우 일반적으로 일정 수준의 실행 시간을 포기합니다. 어셈블리 코드로 모든 것을 작성하면 최고의 속도를 얻을 수 있습니다. 그건 ...

YouTube 알아요? 아마도 가장 높은 대역폭의 사이트일까요, 아니면 넷플릭스의 사이트일까요? 그들은 코드의 많은 부분을 파이썬으로 작성하는데, 이는 최고의 성능을 위해 개발되지 않은 고도로 모듈화 된 언어입니다.

문제는 문제가 발생하고 사용자가 비디오를 느리게로드하는 것에 대해 불평하는 경우 그 속도가 궁극적으로 Python의 느린 실행 속도에 기인하는 시나리오는 많지 않다는 것입니다. 그러나 파이썬의 빠른 재 컴파일과 타입 검사없이 새로운 것을 시도 할 수있는 모듈 식 기능은 아마도 엔지니어가 잘못되고있는 것을 매우 빠르게 디버깅 할 수있게 해줄 것입니다. ( "와우. 새로운 인턴은 새로운 SQL 하위 쿼리를 수행하는 루프를 작성했습니다. 모든 결과에 대해. ") 또는 ("Firefox는 이전 캐싱 헤더 형식을 더 이상 사용하지 않으며 새로운 라이브러리를 쉽게 설정하기 위해 Python 라이브러리를 만들었습니다 ")

그런 의미에서, 실행 시간의 관점에서도 모듈 식 언어는 병목 현상이 무엇인지 발견하면 코드를 재구성하는 것이 더 쉬워 져 최상의 방식으로 작동 할 수 있기 때문에 더 빠르다고 생각할 수 있습니다. 따라서 많은 엔지니어들이 성능 저하가 예상했던 위치에 있지 않다고 말할 것입니다 (사실 DID 최적화가 거의 필요하지 않았거나 기대했던 방식으로 작동하지 않았습니다!)


0

예, 아니오 다른 사람들이 먼저 가독성을위한 프로그램을 언급 한 다음 효율성을 높였습니다. 그러나 읽기 쉽고 효율성이 높은 표준 사례가 있습니다. 대부분의 코드는 드물게 실행되므로 어쨌든 코드를 최적화해도 큰 이점을 얻지 못합니다.

Java는 더 작은 함수 호출을 인라인 할 수 있으므로 함수 작성을 피할 이유가 거의 없습니다. 최적화 프로그램은 더 읽기 쉬운 코드로 더 잘 작동하는 경향이 있습니다. 이론적으로 더 빨리 실행해야하는 단축 법을 보여주는 연구가 있습니다. 실제로 더 오래 걸립니다. JIT 컴파일러는 코드가 작고 자주 실행되는 부분을 식별하고 최적화 할 수 있도록 더 잘 작동합니다. 나는 그것을 시도하지는 않았지만 상대적으로 거의 호출되지 않는 하나의 큰 함수는 컴파일되지 않을 것으로 기대합니다.

이것은 Java에는 적용되지 않을 수도 있지만 한 연구에 따르면 다른 메모리 참조 모델이 필요하기 때문에 더 큰 함수가 실제로 느리게 실행되는 것으로 나타났습니다. 하드웨어 및 최적화 프로그램에 따라 다릅니다. 작은 모듈의 경우 메모리 페이지 내에서 작동하는 명령이 사용되었습니다. 함수가 페이지에 맞지 않을 때 필요한 지시 사항보다 빠르고 작습니다.

코드를 최적화하는 동안 가치가있는 경우가 있지만 일반적으로 코드의 위치를 ​​파악하려면 코드를 프로파일 링해야합니다. 나는 종종 내가 예상했던 코드가 아니라는 것을 알았습니다.

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