Aproach tốt nhất để mã hóa trong môi trường biên dịch chậm là gì


15

Tôi đã sử dụng mã hóa theo C # theo kiểu TDD - viết / hoặc thay đổi một đoạn mã nhỏ, biên dịch lại trong 10 giây toàn bộ giải pháp, chạy lại các bài kiểm tra và một lần nữa. Dễ dàng...

Phương pháp phát triển đó đã làm việc rất tốt đối với tôi trong một vài năm, cho đến một năm trước khi tôi phải quay lại mã hóa C ++ và thực sự cảm thấy rằng năng suất của tôi đã giảm đáng kể kể từ đó. C ++ là ngôn ngữ không phải là vấn đề - tôi đã có khá nhiều trải nghiệm về C ++ dev ... nhưng trong quá khứ.

Năng suất của tôi vẫn ổn đối với một dự án nhỏ, nhưng nó còn tệ hơn khi tăng quy mô dự án và một khi thời gian biên dịch đạt hơn 10 phút thì nó thực sự tồi tệ. Và nếu tôi tìm thấy lỗi, tôi phải bắt đầu biên dịch lại, v.v ... Điều đó hoàn toàn gây khó chịu.

Do đó, tôi đã kết luận rằng trong một khối nhỏ (như trước đây) không được chấp nhận - mọi khuyến nghị làm thế nào tôi có thể tập thói quen viết mã cũ trong một giờ hoặc lâu hơn, khi xem lại mã theo cách thủ công (mà không cần dựa vào trình biên dịch C # nhanh) và chỉ biên dịch lại / chạy lại các bài kiểm tra đơn vị một lần trong vài giờ.

Với C # và TDD, thật dễ dàng để viết mã theo cách tiến hóa - sau hàng tá lần lặp lại, bất cứ điều gì tào lao tôi bắt đầu đều kết thúc bằng một mã tốt, nhưng nó không còn hiệu quả với tôi nữa (trong quá trình biên dịch chậm Môi trường).


stackoverflow.com/questions/5078409/ đá Những thứ này có lẽ nên được hợp nhất / ở một nơi.
Ben L

Xem laso stackoverflow.com/questions/373142/ Khắc để tăng tốc thời gian biên dịch C ++.
Nhật thực

2
Bắt đầu một cuộc đấu kiếm . ; p
Steven Jeuris

Lần cuối cùng tôi sử dụng C ++ một cách nghiêm túc, sử dụng các tiêu đề được biên dịch trước đã cắt giảm thời gian biên dịch theo hệ số bốn.
gnasher729

Câu trả lời:


16

Một vài điều tôi nghĩ đến:

  1. Sử dụng biên dịch phân tán . Bạn có thể làm điều này với GCC ("distCC"?) Hoặc VC ( Xoreax 'IncrediBuild không chính xác với giá rẻ, nhưng đáng giá từng xu chi cho nó.).

  2. Chia dự án của bạn thành các thư viện được tải động và cố gắng cẩn thận để giảm thiểu các phụ thuộc vào chúng. Thực thi nhỏ hơn liên kết nhanh hơn nhiều.

  3. Chương trình chống lại các dự án thử nghiệm nhỏ hơn là toàn bộ ứng dụng lớn.

  4. Sử dụng lập trình meta-meta để thực hiện các thuật toán tại thời gian biên dịch . Vâng, điều này thực sự sẽ tăng thời gian biên dịch, nhưng nó cũng sẽ làm giảm các vòng quay cần thiết để thử nghiệm: Nếu nó biên dịch tốt, nó đã hoàn thành.

  5. Đầu tư vào phần cứng . Nhiều nhân CPU hơn (trong máy của bạn hoặc trong các máy khác) sẽ tự hỏi với quá trình biên dịch phân tán và rất nhiều bộ nhớ cộng với một đĩa nhanh (SSD thay vì HDD) sẽ giúp ích rất nhiều. Nếu bạn có hệ thống 64 bit và lượng RAM tối nghĩa, việc biên dịch trên đĩa RAM có thể giúp tăng tốc đáng kinh ngạc.


1
bộ đệm trình biên dịch thực sự là một ý tưởng tốt hơn so với biên dịch phân tán theo kinh nghiệm của tôi.
pqnet

Nói về đĩa RAM so với SSD, tôi khá ngạc nhiên khi nó không mang lại sự gia tăng quá nhiều về tốc độ biên dịch. Dự án hiện tại của tôi (Java trên Android) biên dịch từ trạng thái sạch trong ~ 45 giây từ SSD và trong ~ 40 giây từ đĩa RAM (và toàn bộ chuỗi công cụ nằm trong đĩa RAM, không chỉ là nguồn). Không phải là một sự gia tăng đáng kể, tôi nói.
Haspemulator

10

Một giải pháp kỹ thuật khác chưa được đề cập bởi những người khác là chuyển sang Ổ đĩa thể rắn thay vì ổ cứng thông thường. Trong một dự án trước đây tôi đã làm việc, SSD đã giảm thời gian xây dựng từ phạm vi 30 phút xuống còn 3.

Tất nhiên, chúng rất tốn kém. Đối với ông chủ của bạn, hãy tính giá của thời gian dành cho nhà phát triển bị mất so với giá của khoản đầu tư một lần. Đầu tư có thể trả cho chính nó trong một vài tháng.


6
Nó thật thú vị. Điều đó nói rằng 90% thời gian xây dựng là độ trễ đĩa I / O.
Mike Dunlavey

Tôi chưa thấy giảm 90%, nhưng đáng kể. Nó dường như không tăng tốc độ biên dịch, nhưng nó chắc chắn tăng tốc độ liên kết. Nếu bạn đang thực hiện các thay đổi nhỏ cho một dự án lớn (vì vậy không có nhiều sự biên dịch trong một thay đổi) và làm lại, bạn có thể có được điều này. (Đây là Visual Studio 2008, sử dụng C ++.)
David Thornley

1
Đây là một ý tưởng tốt. Ngoài ra, việc gắn một phần RAM trên hệ thống tệp của bạn sẽ hoạt động nhanh và giá rẻ.
Goran Jovic

2
Ramdisk thậm chí còn nhanh hơn (và rẻ hơn).
SK-logic

1
@ John: Vâng, một trình biên dịch được viết tốt nên (IMHO) bị ràng buộc I / O.
Mike Dunlavey

3

Lập kế hoạch nhiều hơn, mã trong các khối lớn hơn, viết các bài kiểm tra tích hợp thay vì kiểm tra đơn vị và chạy bộ xây dựng + kiểm tra qua đêm.


3

Thời gian biên dịch dài đôi khi là một vấn đề, nhưng mô đun hóa đã được đề cập có thể giúp khắc phục điều đó (chủ yếu).

Nghiêm trọng hơn nữa là bị mắc kẹt trong một môi trường mà bạn hoàn toàn không thể biên dịch, trong đó mọi thay đổi mã phải được gửi đến một bộ phận khác trên lục địa khác để áp dụng vào môi trường thử nghiệm / phát triển, một quá trình có thể mất nhiều ngày để hoàn thành.

Tôi hiện đang làm việc trong một môi trường như vậy và hệ thống này đã khiến tôi mất một tuần thời gian (và dự án chỉ có ngân sách trong 4 tuần tổng thời gian trước khi hết tiền) chỉ để cài đặt phiên bản ban đầu của các thay đổi của chúng tôi (và sau đó họ đã phạm sai lầm khiến một phần của các tệp không được máy chủ ứng dụng chọn, vì vậy chúng tôi đang xem xét thêm vài ngày chậm trễ). Mỗi thay đổi nhỏ bây giờ (giả sử chúng tôi tìm thấy một cái gì đó trong thử nghiệm cần sửa chữa, như tình trạng lỗi bị bỏ lỡ) có thể gây ra sự chậm trễ của một ngày khác hoặc hơn.

Trong những điều kiện như vậy, bạn cố gắng đảm bảo chắc chắn rằng bạn không thể có bất kỳ lỗi nào trước cả khi cố gắng để mã của bạn được biên dịch. Cảm giác gần giống như tôi trở lại lập trình máy tính lớn, nơi chúng tôi có 5 phút thời gian CPU mỗi tháng cho tất cả các công việc biên dịch và kiểm tra.


1
Chàng trai, đó là một tình huống từ địa ngục. Tôi nhớ những ngày máy tính lớn. Chúng tôi đã thực hiện rất nhiều "kiểm tra bàn" mã. Thật đáng kinh ngạc bao nhiêu đã được thực hiện theo cách đó, chẳng hạn như mô phỏng vô tận của các chuyến bay lên mặt trăng.
Mike Dunlavey

3

Tôi có thể dễ dàng nhớ khi các bản dựng mất nhiều thời gian. Một số cách tiếp cận giảm nhẹ:

  • Xây dựng hệ thống bằng cách kết hợp các thư viện hoặc dlls. Theo cách đó, khi bạn sửa đổi một số mã, phần duy nhất cần được biên dịch lại là phần của bạn.
  • Số lượng điểm trong mã bạn cần chỉnh sửa để triển khai một tính năng không chỉ ảnh hưởng đến việc bạn phải chỉnh sửa bao nhiêu mà còn cả tần suất bạn mắc lỗi, khuếch đại vòng lặp biên dịch-gỡ lỗi-chỉnh sửa-biên dịch. Bất cứ điều gì làm giảm sự dư thừa của mã, chẳng hạn như DRY, đều có ích.
  • Nếu bạn đang ở trong trình gỡ lỗi và có thể chỉnh sửa, biên dịch lại và tiếp tục mà không cần rời khỏi trình gỡ lỗi, điều đó thực sự hữu ích.

2

Hơn 10 phút cho một biên dịch? Nghiêm túc?

Bạn có đang sử dụng một IDE xây dựng gia tăng (ví dụ: Eclipse) không? Nếu không, có lẽ bạn nên làm, nó sẽ thực hiện biên dịch cơ bản trong vài giây thay vì vài phút.

Hay bạn đang nói về công cụ tích hợp, nơi bạn cần xây dựng toàn bộ ứng dụng để kiểm tra sự thay đổi của mình? Nếu vậy, hãy xem các thử nghiệm nhỏ hơn để đảm bảo các lỗi lớn nằm ngoài mã của bạn trước khi phải thực hiện quá trình xây dựng đầy đủ.


5
10 phút là nhỏ. Tôi đã làm việc cho một dự án mất một giờ để biên dịch và liên kết từ đầu trên một máy lõi đơn, PCH và tất cả. Tất nhiên, ngoại trừ bản phát hành tự động, không ai sẽ xây dựng nó chỉ trên một lõi bộ xử lý, nhưng vẫn ... Nếu bạn phải thay đổi một cái gì đó trong tiêu đề bao gồm mọi nơi (thao tác chuỗi, xử lý lỗi), bạn có thể gặp rắc rối.
sbi

2
Được sử dụng để làm việc (nhiều năm trước) trên một hệ thống đã mất, để xây dựng hoàn chỉnh, 48 giờ để biên dịch. Tất nhiên, một bản dựng hoàn chỉnh chỉ được bắt đầu vào tối thứ sáu, hy vọng sẽ được thực hiện khi chúng tôi trở lại văn phòng vào thứ hai. Thay vào đó, chúng tôi xây dựng các mô-đun nhỏ khi cần thiết (giả sử một DLL).
jwenting

2
-1 cho tất cả các ý kiến ​​trên nếu tôi có thể +1 thành TrueDub. Có, nếu bạn đang biên dịch lại mọi thứ thì có thể mất một thời gian rất dài. Tuy nhiên, nếu bất kỳ suy nghĩ nào được đưa ra cho quản lý phụ thuộc thì toàn bộ 10 giờ dự án biên dịch lại có thể có các biên dịch lại tăng dần trong vòng chưa đầy một phút là chuẩn mực. Tất cả các bạn nên xấu hổ vì bản thân đã lãng phí thời gian của nhà tuyển dụng chờ đợi cho các biên dịch lại của bạn khi áp dụng một chút thông minh sẽ tiết kiệm rất nhiều thời gian.
Dunk

2
Và nếu bạn làm việc trong một cửa hàng nhỏ tình cờ ngồi trong một dự án vài MLoC, thì điều đó có nghĩa là một phần đáng kể của mã đã cũ, bắt đầu từ một thập kỷ trước vì nhiều dự án nhỏ, trong đó tốc độ biên dịch không bao giờ là vấn đề, và quản lý phụ thuộc là rất tệ. Vì vậy, bạn sẽ nói với một công ty như vậy để ném tất cả điều này và dành một thập kỷ nữa để viết lại nó?
sbi

2
@Dunk: Đó là một công ty nhỏ, với ít hơn một chục nhà phát triển làm việc trong một dự án nhiều MLoC. Điều đó rất khác với hàng trăm nhà phát triển đang làm như vậy: bạn không thể viết lại bất cứ điều gì từ đầu, bởi vì bạn cần nhiều năm để làm như vậy. Nhiều như tôi ghét ý tưởng, đầu tư vào biên dịch phân tán là khả thi về mặt kinh tế, viết lại thì không. Ồ, và tôi được thừa hưởng những giao diện đó. :-xTôi đã không ở đó một thập kỷ trước, khi họ đã nghĩ đến. (Tôi đã thay đổi rất nhiều mã đó để sử dụng TMP, để tìm thêm lỗi khi biên dịch và ít hơn trong lĩnh vực này.)
sbi

2

Đầu tiên, tại sao phải mất quá nhiều thời gian để biên dịch ở nơi đầu tiên?

  • Môi trường của bạn (IDE, make, anything) có hỗ trợ các bản dựng gia tăng không? Hãy chắc chắn rằng bạn chỉ biên dịch lại các thay đổi, chứ không phải toàn bộ.
  • Nếu bạn có một máy đa lõi, IDE của bạn có thể hỗ trợ biên dịch song song. Tôi biết một thực tế rằng Visual Studio làm điều đó. Rõ ràng gcc cũng vậy. Vì vậy, có được một máy tốt hơn, và cho phép biên dịch song song.
  • Xem xét sử dụng các tiêu đề được biên dịch trước.
  • Nếu bạn thử tất cả, và quá trình biên dịch vẫn chậm, hãy xem lại mã của bạn. Tìm kiếm sự phụ thuộc không cần thiết. Bạn có bao gồm một tiêu đề trong đó một tuyên bố chuyển tiếp sẽ là đủ? Cân nhắc sử dụng thành ngữ PIMPL để giảm sự phụ thuộc vào các tiêu đề.

Nếu sau tất cả thời gian xây dựng của bạn vẫn chậm, thì hãy giải quyết vấn đề: tạo nhiều dự án thử nghiệm nhỏ và làm việc trên từng cá nhân. Hãy chắc chắn rằng bạn có một hệ thống xây dựng hàng đêm tự động thực hiện kiểm tra mới, xây dựng mọi thứ và tự động chạy tất cả các bài kiểm tra đơn vị.

Cuối cùng, nếu bạn vẫn mất nhiều thời gian để kiểm tra các thay đổi của mình, thì hãy suy nghĩ nhiều hơn về chúng. Hãy chắc chắn thực hiện một khác biệt trong hệ thống kiểm soát phiên bản của bạn và xem xét cẩn thận tất cả các thay đổi trước khi thử nghiệm. Nói tóm lại, điều này rất giống với việc phát triển hệ thống nhúng, trong đó thời gian quay vòng cho một bài kiểm tra dài và khả năng kiểm tra trạng thái của hệ thống bị hạn chế.

Điều này dẫn tôi đến một suy nghĩ khác: sử dụng mã của bạn để sử dụng đăng nhập. Bằng cách này, bạn có thể thấy vấn đề là gì mà không cần xây dựng lại và chạy lại hàng tá lần.


2
Tôi không chắc chắn nếu GCC hỗ trợ biên dịch song song nhiều như thực tế là các công cụ tạo hoặc tương tự sẽ bắt đầu một số bản sao của GCC nếu bạn cũng nói như vậy.
Zachary K

1
+1 cho PIMPL. Tôi đã làm việc trong một dự án mà thời gian xây dựng vượt khỏi tầm kiểm soát. Trong dự án đó, tôi không quan tâm đến việc có bao nhiêu tiêu đề khác được bao gồm trong mỗi tiêu đề. Trong dự án tiếp theo của tôi, tôi đã biến nó thành một điểm để giảm thiểu điều này bằng cách sử dụng rộng rãi PIMPL. Thời gian xây dựng tiếp tục tuyệt vời mặc dù dự án thứ hai có thể gấp đôi quy mô của dự án đầu tiên.
Jason B

1

Bạn có thể cần một cách tiếp cận đa prong:

1) Hệ thống xây dựng nhanh hơn. Càng nhiều lõi / ram / đĩa nhanh càng tốt. Đối với các dự án C ++ lớn hơn, bạn sẽ thấy rằng đĩa thường là một bộ giới hạn, vì vậy hãy chắc chắn rằng bạn có những cái nhanh.

2) Nhiều mô đun hóa của dự án. Phá vỡ mọi thứ để những thay đổi không thể dễ dàng gây ra sự biên dịch lại toàn bộ mọi thứ. Thành thật mà nói, đẩy càng nhiều thứ cơ bản càng tốt vào các tệp dll / so riêng biệt để một phần của dự án có thể được tách hoàn toàn khỏi phần còn lại.

3) Bản dựng tăng dần / bản dựng phân tán / bộ nhớ đệm phù hợp với môi trường của bạn. Trên một số hệ thống, distcc (tòa nhà phân tán) và ccache (bộ nhớ đệm của công cụ được xây dựng một phần) có thể tiết kiệm rất nhiều thời gian biên dịch.

4) Hãy chắc chắn rằng bản dựng của bạn có thể được song song tốt. Trong môi trường Makefile đặc biệt, không khó để gặp tình huống bạn vô tình thiết lập Makefiles sao cho bạn không thể xây dựng song song.


0

Ghi nhật ký mở rộng và xác nhận nội bộ đã hữu ích cho thời gian quay vòng dài. Khi quá trình xây dựng của bạn hoàn tất, một lần chạy có thể tiết lộ một loạt các vấn đề có thể xảy ra cùng một lúc.

Khi xử lý các thuật toán hoặc sổ sách kế toán khá phức tạp, có thể hữu ích khi bao gồm một phiên bản đơn giản hóa cao song song với phiên bản 'thực'. Trong bất kỳ hoạt động, bạn có dữ liệu tham khảo hữu ích bao gồm.


0

Những gì @sbi và @Michael Kohne nói.

Dành thời gian và năng lượng cho quá trình xây dựng chính nó. Ngày xửa ngày xưa, chúng tôi đã có một sản phẩm trang nghiêm, trưởng thành mất hơn một giờ để xây dựng hoàn chỉnh. Đã dành nhiều thời gian và công sức để sửa chữa những gì mà các phụ thuộc xây dựng tuyên bố, và sau đó, sửa chữa / giảm bớt những gì chúng thực sự là. Thời gian xây dựng giảm xuống ~ 30 phút.

Thay đổi công cụ xây dựng bỏ nó nhiều hơn. Đối với một dự án gồm nhiều phần, 'scons' có thể thực hiện tất cả các biên dịch trước khi thực hiện bất kỳ liên kết nào. 'Make' bằng cách sử dụng nhiều tệp tạo tệp thực hiện một biên dịch của một dự án trước các liên kết của dự án đó, sau đó tiếp tục.

Điều đó đưa chúng ta đến điểm mà tất cả các lệnh biên dịch riêng lẻ có thể được thực hiện song song. 'distcc' trên các máy chậm, tạo / scons -j8 trên các máy đa lõi. Điều đó mang lại đầy đủ các bản dựng xuống trong một vài phút.

Trong một ánh sáng khác, tạo ra một quy trình xây dựng hàng đêm tự động. Theo cách đó, nếu một cái gì đó có vấn đề được cam kết với kho lưu trữ nguồn của bạn, người đầu tiên đến nơi làm việc, xem và khắc phục sự cố, có thể ngăn không cho nhiều người thực hiện nhiều lần xây dựng thất bại.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.