느린 컴파일 환경에서 코딩하기에 가장 좋은 방법은 무엇입니까


15

나는 C #에서 TDD 스타일로 코딩하는 데 익숙했습니다. 작은 코드 덩어리를 작성 / 변경하고 전체 솔루션을 10 초 안에 다시 컴파일하고 테스트를 다시 실행하십시오. 쉬운...

그 개발 방법론은 지난 몇 년 동안 C ++ 코딩으로 돌아 가야 할 때까지 몇 년 동안 나에게 아주 잘 작동했으며 그 이후로 내 생산성이 크게 떨어 졌다고 생각합니다. 언어로서의 C ++는 문제가되지 않습니다. 저는 C ++ 개발자 경험이 많았지 만 과거에는 그랬습니다.

소규모 프로젝트의 생산성은 여전히 ​​괜찮지 만 프로젝트 크기가 증가하면 컴파일 시간이 10 분 이상되면 정말 나빠집니다. 그리고 오류를 발견하면 다시 컴파일을 시작해야합니다. 순전히 실망 스럽습니다.

따라서 작은 덩어리에서 (이전과 같이) 받아 들일 수 없다는 결론을 내 렸습니다. 권장 사항을 수동으로 검토 할 때 (빠른 C # 컴파일러에 의존하지 않고) 한 시간 정도 코딩의 습관에 빠져들 수있는 방법 , 두 시간에 한 번만 재 컴파일 / 재실행 단위 테스트를 수행합니다.

C #과 TDD를 사용하면 진화 방식으로 코드를 작성하는 것이 매우 쉽습니다. 처음 시작한 쓰레기가 좋은 코드로 끝나지 만 더 이상 나에게 적합하지 않습니다 (느린 컴파일에서) 환경).


stackoverflow.com/questions/5078409/… 이것들은 아마도 한 곳에서 합쳐 져야합니다.
벤 L

C ++ 컴파일 속도를 높이 려면 laso stackoverflow.com/questions/373142/… 를 참조하십시오 .
Eclipse

2
검 싸움을 시작하십시오 . ; p
Steven Jeuris

사전 컴파일 된 헤더를 사용하여 C ++을 본격적으로 마지막으로 사용한 경우 컴파일 시간을 4 배로 줄였습니다.
gnasher729 2016 년

답변:


16

몇 가지 생각이 떠 오릅니다.

  1. 의 사용을 확인 분산 컴파일 . GCC ( "distCC"?) 또는 VC를 사용하여이 작업을 수행 할 수 있습니다 ( Xoreax 'IncrediBuild 는 정확히 저렴하지는 않지만 모든 센트가 소비됩니다.).

  2. 프로젝트 를 동적으로로드 된 라이브러리로 분할 하고주의하여 라이브러리에 대한 종속성을 최소화하십시오. 작은 실행 파일은 훨씬 빠르게 연결됩니다.

  3. 에 대한 프로그램 작은 테스트 프로젝트 가 아닌 전체 큰 응용 프로그램입니다.

  4. 컴파일 타임에 알고리즘수행 하기 위해 템플릿-메타 프로그래밍을 사용 하십시오 . 예, 실제로 컴파일 시간이 늘어나지 만 테스트에 필요한 처리 시간도 줄어 듭니다. 제대로 컴파일되면 완료됩니다.

  5. 하드웨어에 투자하십시오 . 더 많은 CPU 커널 (컴퓨터 또는 다른 시스템)은 분산 컴파일로 궁금 할 것입니다. 많은 메모리와 빠른 디스크 (HDD 대신 SSD)가 도움이 될 것입니다. 64 비트 시스템과 음란 한 RAM이있는 경우 RAM 디스크에서 컴파일하면 속도가 크게 향상 될 수 있습니다.


1
컴파일러 캐시는 실제로 내 경험에서 분산 컴파일보다 더 좋습니다.
pqnet

RAM 디스크와 SSD에 관해서는 컴파일 속도가 크게 향상되지 않았다는 사실에 놀랐습니다. 현재 프로젝트 (Android의 Java)는 SSD에서 ~ 45 초, RAM 디스크에서 ~ 40 초 만에 깨끗한 상태에서 컴파일됩니다 (그리고 전체 툴 체인은 소스가 아닌 RAM 디스크에 있습니다). 나는 크게 증가하지 않았다고 말했다.
Haspemulator

10

다른 사람들이 아직 언급하지 않은 또 다른 기술 솔루션은 일반 하드 드라이브 대신 솔리드 스테이트 드라이브로 전환하는 것입니다. 내가 작업했던 이전 프로젝트에서 SSD는 빌드 시간을 30 분에서 3 분으로 줄였습니다.

물론 비용이 많이 듭니다. 상사를 위해 일회성 투자 가격 대비 개발자 시간 손실 가격을 계산하십시오. 투자는 아마도 몇 달 안에 그 자체로 지불 할 것입니다.


6
그 흥미 롭군요. 즉, 빌드 시간의 90 %가 I / O 디스크 대기 시간입니다.
Mike Dunlavey

나는 90 % 감소를 보지 못했지만 실질적인 감소를 보았습니다. 컴파일 속도를 높이는 것 같지는 않지만 링크 속도를 분명히합니다. 큰 프로젝트를 약간 변경하고 (변경에 컴파일이 많지 않음) 다시 연결하는 경우이를 얻을 수 있습니다. (이것은 C ++를 사용하여 비주얼 스튜디오 2008입니다.)
데이빗 쏜리

1
이것은 좋은 생각입니다. 또한 파일 시스템에 RAM의 일부를 마운트하면 빠르게 작동하며 저렴합니다.
Goran Jovic

2
램 디스크는 더 빠르며 저렴합니다.
SK-logic

1
@John : 예, 잘 작성된 컴파일러 (IMHO)는 I / O 바인딩이어야합니다.
Mike Dunlavey 2016 년

3

더 많은 계획, 더 큰 청크로 코딩, 단위 테스트 대신 통합 테스트를 작성하고 밤새 빌드 + 테스트 스위트를 실행하십시오.


3

컴파일 시간이 길면 문제가 될 수 있지만 이미 언급 한 모듈화를 통해이를 극복 할 수 있습니다 (대부분).

전혀 코드를 컴파일 할 수없는 환경에서 훨씬 더 심각한 문제가 발생하고 있습니다. 모든 코드 변경은 테스트 / 개발 환경에 적용하기 위해 다른 대륙의 다른 부서에 제출해야합니다.이 과정은 완료하는 데 며칠이 걸릴 수 있습니다.

나는 지금 그러한 환경에서 일하고 있으며이 시스템은 일주일에 걸쳐 이미 비용이 들었습니다 (그리고 프로젝트는 돈이 다 ​​떨어지기 전에 총 4 주 동안 예산이 있습니다). (그리고 그들은 응용 프로그램 서버가 파일의 일부를 선택하지 못하게하는 실수를했기 때문에 며칠 더 지연되는 것을보고 있습니다). 이제 각각의 사소한 변경 (예 : 누락 된 오류 조건과 같이 수정이 필요한 테스트에서 발견)으로 인해 하루 이상 지연 될 수 있습니다.

이러한 조건에서는 코드를 컴파일하기 전에 오류가 없는지 확실하게 확인하려고합니다. 메인 프레임 프로그래밍으로 돌아가는 것처럼 느껴집니다. 모든 컴파일 및 테스트 작업에 매월 5 분의 CPU 시간을 사용할 수 있습니다.


1
소년, 그것은 지옥의 상황입니다. 메인 프레임 시절을 기억합니다. 우리는 많은 "데스크 검사"코드를 수행했습니다. 달까지의 비행에 대한 끝없는 시뮬레이션과 같은 방식으로 얼마나 많은 일을했는지 ​​놀랍습니다.
Mike Dunlavey

3

빌드가 오래 걸렸을 때를 쉽게 기억할 수 있습니다. 일부 완화 방법 :

  • 라이브러리 또는 dll을 결합하여 시스템을 빌드하십시오. 이렇게하면 일부 코드를 수정할 때 재 컴파일해야하는 유일한 부분이 사용자의 부분입니다.
  • 기능을 구현하기 위해 편집해야하는 코드의 포인트 수는 편집의 양에 영향을 줄뿐만 아니라 버그를 넣는 빈도에 따라 컴파일-디버그-편집-컴파일 루프를 증폭시킵니다. DRY와 같은 코드 중복성을 줄이는 것이 도움이됩니다.
  • 디버거에 있고 디버거를 떠나지 않고 편집, 재 컴파일 및 계속할 수 있다면 정말 도움이됩니다.

2

컴파일 10 분 이상? 진심이야?

증분 빌드 (예 : Eclipse)를 수행하는 IDE를 사용하고 있습니까? 그렇지 않으면 아마도 몇 분이 아닌 몇 초 안에 기본 컴파일을 수행해야합니다.

또는 변경 사항을 테스트하기 위해 전체 앱을 빌드해야하는 통합에 대해 이야기하고 있습니까? 그렇다면 전체 테스트를 수행하기 전에 더 작은 테스트를 통해 주요 버그가 코드에 없는지 확인하십시오.


5
10 분은 작습니다. 나는 단일 코어 컴퓨터, PCH 및 모두에서 처음부터 컴파일하고 링크하는 데 1 시간이 걸리는 프로젝트를 위해 일했습니다. 물론, 자동 릴리스 빌드를 제외하고는 아무도 하나의 프로세서 코어에만 빌드하지는 않지만 여전히 ... 어디에서나 포함 된 헤더 (문자열 조작, 오류 처리)에서 무언가를 변경해야한다면 혼란 스러울 수 있습니다.
sbi

2
완전한 빌드를 위해 컴파일하는 데 48 시간이 걸린 시스템에서 (몇 년 전) 작동했습니다. 물론 완전한 빌드는 금요일 저녁에만 시작되었으며 월요일에 사무실로 돌아 왔을 때 완료되기를 바랍니다. 대신 필요에 따라 작은 모듈 (예 : 단일 DLL)을 구축했습니다.
jwenting

2
TrueDub에 +1 할 수 있으면 위의 모든 의견에 -1입니다. 예, 모든 것을 다시 컴파일하는 경우 시간이 오래 걸릴 수 있습니다. 그러나 의존성 관리에 대한 생각이 있다면 10 분 전체 재 컴파일 프로젝트가 1 분 이내에 증분 재 컴파일을 할 수 있습니다. 약간의 지능을 적용하면 막대한 시간을 절약 할 수 있도록 고용주가 재 컴파일을 기다리는 데 시간을 허비하는 것에 대해 모두 부끄러워해야합니다.
덩크

2
여러 MLoC 프로젝트에 참여하는 소규모 상점에서 작업하는 경우 10 년 전에 코드의 상당 부분이 오래되어 컴파일 속도가 문제가되지 않은 여러 소규모 프로젝트로 시작되었음을 의미합니다. 그리고 의존성 관리는 매우 나쁘다. 그렇다면 그러한 회사에이 모든 것을 버리고 다시 쓰도록 10 년을 쓰라고 말할 것입니까?
sbi

2
@ 덩크 (Dunk) : 소규모 회사였으며, 12여 명의 개발자가 멀티 MLoC 프로젝트를 수행하고 있습니다. 이는 수백 명의 개발자가하는 것과는 매우 다릅니다 . 몇 년이 걸리기 때문에 처음부터 아무 것도 다시 쓸 수 없습니다 . 내가 아이디어를 싫어하는 한 분산 컴파일에 투자하는 것은 경제적으로 가능했으며 재 작성은 불가능했습니다. 아, 그리고 나는 그 인터페이스를 물려 받았습니다. :-x나는 그들이 생각했던 10 년 전에 거기에 없었다. (TMP를 사용하도록 많은 코드를 변경하여 컴파일시 더 많은 오류를 발견하고 현장에서 더 적게 발견했습니다.)
sbi

2

첫째, 처음에 컴파일하는 데 왜 그렇게 오래 걸립니까?

  • 환경 (IDE, make 등)이 증분 빌드를 지원합니까? 전체가 아닌 변경 사항 만 다시 컴파일해야합니다.
  • 멀티 코어 머신을 사용하는 경우 IDE에서 병렬 컴파일을 지원할 수 있습니다. Visual Studio가 그 사실을 알고 있습니다. 분명히 gcc도 마찬가지입니다. 따라서 더 나은 기계를 얻고 병렬 컴파일을 활성화하십시오.
  • 미리 컴파일 된 헤더 사용을 고려하십시오.
  • 모든 것을 시도해도 컴파일 속도가 느리면 코드를 검토하십시오. 불필요한 종속성을 찾으십시오. 전달 선언이 충분한 헤더를 포함하고 있습니까? 헤더에 대한 종속성을 줄이려면 PIMPL 관용구 사용을 고려하십시오.

이 모든 것이 끝난 후에도 빌드 시간이 여전히 느리다면 문제를 해결하십시오. 많은 작은 테스트 프로젝트를 만들고 각각 개별적으로 작업하십시오. 새로운 체크 아웃을 수행하고 모든 것을 구축하며 모든 단위 테스트를 자동으로 실행하는 자동화 된 야간 빌드 시스템이 있는지 확인하십시오.

마지막으로 변경 사항을 테스트하는 데 시간이 오래 걸리면 더 많은 생각을하십시오. 버전 관리 시스템을 점검하고 테스트하기 전에 모든 변경 사항을주의 깊게 검토하십시오. 요컨대 이것은 테스트에 소요되는 시간이 길고 시스템 상태를 검사하는 능력이 제한되는 임베디드 시스템 개발과 매우 유사합니다.

로깅을 사용하도록 코드를 계측하십시오. 이 방법으로 수십 번의 재 구축 및 재실행없이 문제가 무엇인지 확인할 수 있습니다.


2
GCC가 병렬 컴파일을 지원하는지 여부는 확실하지 않습니다. 제작 도구 또는 이와 유사한 도구가 GCC 사본을 여러 개 시작하면 사실입니다.
Zachary K

1
PIMPL의 경우 +1 빌드 시간이 통제 할 수없는 프로젝트를 진행했습니다. 이 프로젝트에서는 각 헤더에 포함 된 다른 헤더 수에 대해서는 신경 쓰지 않았습니다. 다음 프로젝트에서는 PIMPL을 광범위하게 사용하여이를 최소화 할 것을 강조했습니다. 두 번째 프로젝트가 첫 번째 프로젝트의 두 배 일지라도 빌드 시간은 계속 좋습니다.
Jason B

1

아마도 여러 가지 방법이 필요할 것입니다.

1) 더 빠른 빌드 시스템. 당신이 감당할 수있는만큼의 코어 / 램 / 패스트 디스크. 더 큰 C ++ 프로젝트의 경우 디스크가 종종 제한 기이므로 빠른 디스크가 있는지 확인하십시오.

2) 프로젝트의 더 모듈화. 변경 사항으로 인해 모든 것이 완전히 다시 컴파일되지 않도록 항목을 분리하십시오. 솔직히 말해서, 프로젝트의 일부가 나머지 부분과 완전히 분리 될 수 있도록 가능한 많은 기본 항목을 별도의 dll / so 파일로 푸시하십시오.

3) 환경에 따라 증분 빌드 / 분산 빌드 / 캐싱. 일부 시스템에서는 distcc (분산 빌딩)와 ccache (부분적으로 구축 된 것들의 캐싱)가 많은 컴파일 시간을 절약 할 수 있습니다.

4) 빌드가 병렬화 될 수 있는지 확인하십시오. 메이크 파일 환경에서, 병렬 빌드를 수행 할 수 없도록 실수로 메이크 파일을 설정 한 상황에 들어가기가 어렵지 않습니다.


0

광범위한 로깅 및 내부 유효성 검사는 처리 시간이 오래 걸리는 데 도움이되었습니다. 빌드가 완료되면 한 번의 실행으로 한 번에 많은 가능한 문제가 표시 될 수 있습니다.

다소 복잡한 알고리즘이나 부기를 처리 할 때 '실제'버전과 함께 매우 단순화 된 버전을 포함하는 것이 도움이 될 수 있습니다. 모든 실행에 유용한 참조 데이터가 포함되어 있습니다.


0

@sbi와 @Michael Kohne의 말.

빌드 프로세스 자체에 시간과 에너지를 소비하십시오. 옛날 옛적에 우리는 완전한 구축을 위해 1 시간 이상이 걸렸던 품위 있고 성숙한 제품을 가지고있었습니다. 빌드 종속성이 주장하는 내용을 수정 한 다음 나중에 실제 상태를 수정 / 축소하는 데 많은 시간과 에너지가 소비되었습니다. 구축 시간이 ~ 30 분으로 단축되었습니다.

빌드 도구를 변경하면 더 떨어졌습니다. 멀티 파트 프로젝트의 경우 'scons'는 링크를 수행하기 전에 모든 컴파일을 수행 할 수 있습니다. 여러 makefile을 사용하는 'make'는 해당 프로젝트의 링크 전에 하나의 단일 프로젝트 컴파일을 수행 한 다음 계속합니다.

그것은 모든 개별 컴파일 명령이 대규모로 병렬 처리 될 수 있다는 점을 우리에게 가져 왔습니다. 느린 머신에서는 'distcc', 멀티 코어 머신에서는 make / scons -j8 그것은 전체 빌드를 몇 분으로 가져 왔습니다.

다른 관점에서 자동화 된 야간 빌드 프로세스를 작성하십시오. 이렇게하면 문제가있는 소스 소스 저장소에 문제가 생길 경우 가장 먼저 작업에 도착한 사람이 문제를보고 해결하여 여러 사람이 여러 번 실패한 빌드를 수행하지 못하게 할 수 있습니다.

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