Là biên dịch dài là một điều của quá khứ?


38

Có vô số câu chuyện chiến tranh về việc một biên dịch có thể mất bao lâu. Ngay cả xkcd cũng đã đề cập đến nó.

Bây giờ, tôi đã không lập trình trong một thời gian dài và hầu như chỉ tiếp xúc với Java và Python (và Python là ngôn ngữ được dịch, không phải là ngôn ngữ được biên dịch). Tôi nhận ra rằng có thể tôi đã không bắt gặp các dự án mất nhiều thời gian để biên dịch, nhưng ngay cả đối với các ứng dụng có kích thước phù hợp, nó đã ngay lập tức đối với tôi (thường được xử lý trong nền bởi IDE) hoặc không quá 30 vài giây hoặc lâu hơn cho một dự án cực kỳ lớn. Ngay cả trong môi trường kinh doanh (nơi diễn ra truyện tranh), tôi chưa bao giờ có mã mất nhiều thời gian để biên dịch.

Có phải tôi đã không được tiếp xúc với các dự án với thời gian biên dịch dài? Đây có phải là một di tích của quá khứ không còn là điều gì đó xảy ra trong thời hiện đại? Tại sao một trình biên dịch sẽ mất một thời gian dài như vậy?


31
Hãy thử biên dịch crom.
UldisK

2
Lấy một bản sao của kernel linux. Làm một bản dựng hoàn chỉnh. Xem cho chính mình. Hoặc Spring từ nguồn nếu bạn là một lập trình viên Java. Như vậy, câu hỏi này có một số câu trả lời đang trả lời câu hỏi như thể đó là một cuộc thăm dò ý kiến ​​("Tôi đã thực hiện các câu trả lời kiểu 30 phút ...") là một dấu hiệu cho thấy bản thân câu hỏi không phù hợp .

Một dự án lớn gần đây đã khiến tôi mất 40 phút để biên dịch (40 000 tệp mã nguồn biên dịch với Maven). Cách giải quyết là tương đương với quá trình biên dịch trên nhiều lõi CPU.
Niklas Rosencrantz

2
Chọn một bản phân phối Linux nguồn (gentoo, LFS, ...) sau đó dành nhiều ngày để biên dịch mọi phần mềm bạn đang cài đặt.
Basile Starynkevitch

6
định nghĩa lâu dài
jwenting

Câu trả lời:


48

Quá trình biên dịch có thể mất một thời gian, đặc biệt đối với các dự án lớn được viết bằng các ngôn ngữ như C, C ++ hoặc Scala. Biên dịch các phần trong nền có thể làm giảm thời gian biên dịch, nhưng đôi khi bạn phải thực hiện một biên dịch mới. Các yếu tố có thể dẫn đến thời gian biên dịch dài bao gồm:

  • Kích thước mã lớn, rõ ràng. Các dự án lớn sẽ có hàng trăm ngàn dòng mã.

  • #includeChỉ thị tiền xử lý của C , có hiệu quả khiến cùng một mã được biên dịch hàng trăm lần. Hệ thống vĩ mô có các vấn đề tương tự, vì nó hoạt động ở cấp độ văn bản. Bộ tiền xử lý thực sự làm tăng kích thước mã thực sự được chuyển đến trình biên dịch. Nhìn vào một tập tin sau khi tiền xử lý (ví dụ thông qua gcc -E) sẽ mở mắt của bạn.

  • Các mẫu của C ++ đã hoàn thành Turing, điều đó có nghĩa là về lý thuyết bạn có thể thực hiện các tính toán tùy ý vào thời gian biên dịch. Không ai thực sự muốn làm điều đó, nhưng thậm chí rất nhiều trường hợp đơn giản đã làm mất khá nhiều thời gian dành cho việc chuyên môn hóa các mẫu.

  • Scala là một ngôn ngữ khá trẻ và trình biên dịch được tối ưu hóa khủng khiếp. Hiện tại, trình biên dịch sử dụng một số lượng lớn các biên dịch biên dịch (C được thiết kế để chỉ yêu cầu hai lần biên dịch). Đánh máy chữ là một trong những cách này và có thể mất một thời gian do hệ thống loại phức tạp đặc trưng bởi ngôn ngữ.

Biên dịch không phải là điều duy nhất cần có thời gian. Sau khi dự án được biên dịch, một bộ thử nghiệm sẽ được chạy. Thời gian dành cho việc này có thể dao động từ vài giây đến vài giờ (nếu các bài kiểm tra được viết kém).


14
Trên thực tế, hệ thống loại của Scala là Turing-Complete, vì vậy việc kiểm tra loại có thể mất một lượng thời gian vô hạn và trình biên dịch không thể xác định điều đó.
Jörg W Mittag

7
Đừng quên tối ưu hóa. Rất nhiều tối ưu hóa mà trình biên dịch C / C ++ sẽ làm rất tốn kém (ví dụ đắt đến mức JIT không đủ khả năng để thực hiện chúng). Đối với trường hợp xấu nhất, hầu hết các chuỗi công cụ đều hỗ trợ tối ưu hóa toàn bộ chương trình, được biết là tăng thời gian xây dựng đáng kể.
Brendan

Tôi đã chấp nhận câu trả lời này bởi vì bạn đã chỉ ra một số điều mà tôi không xem xét, cụ thể là biên dịch toàn bộ so với biên dịch thành từng mảnh và thực tế là các bộ thử nghiệm có thể được đưa vào thời điểm "biên dịch" này.
Thunderforge

1
không chỉ các bộ thử nghiệm - phân tích bảo hiểm mã, đóng gói tự động, triển khai tự động cho hệ thống thử nghiệm; ngày nay có rất nhiều thứ được gói gọn trong một hệ thống xây dựng tích hợp. Và nếu bạn đang giữ cho đến khi nó đến môi trường dev hoặc qa, bạn chắc chắn có thời gian cho một chiếc ghế nhỏ.
corsiKa

1
Câu trả lời tuyệt vời, tôi chỉ lưu ý rằng sự lan truyền của thời gian biên dịch có thể có thể lớn hơn rất nhiều. Tôi đã làm việc trong các dự án mà một bản biên dịch đầy đủ có thể mất từ ​​hai đến ba ngày (vâng, điều đó thật kinh khủng!) Và tôi tưởng tượng có những kẻ phạm tội tồi tệ hơn ngoài kia.
Roy T.

17

Đó không phải là một di tích của quá khứ. Một trong những dự án tôi làm việc đòi hỏi 45 phút để xây dựng sạch từ đầu. Ngoài mã riêng của chúng tôi, chúng tôi cũng phải lấy và xây dựng nguồn từ một số thư viện C và C ++ lớn từ các kho lưu trữ bên ngoài. Biên dịch và liên kết mã C và C ++ đắt tiền về mặt tính toán. Như bạn đã chỉ ra, Python thường được triển khai như một ngôn ngữ được dịch và Java thường sử dụng trình biên dịch JIT (Just in Time), vì vậy các dự án của bạn đang bỏ qua việc biên dịch trả trước và liên kết chi phí hoàn toàn. Giá bạn phải trả là trong thời gian khởi động lâu hơn và (đối với Python ít nhất) tốc độ thực thi chậm hơn.

Khi thời gian xây dựng kéo dài, việc tận dụng các hệ thống tích hợp liên tục như Jenkins hoặc TeamCity trở nên quan trọng hơn . Điều này cho phép các nhà phát triển riêng lẻ (hầu hết) tránh được nỗi đau khi xây dựng từ đầu, trong khi vẫn kiểm tra các thay đổi không phá vỡ bản dựng.


1
javac không " bỏ qua phần tổng hợp trả trước và liên kết chi phí hoàn toàn ". Nó bỏ qua rất nhiều chi phí tối ưu hóa, nhưng nó vẫn chuyển đổi nguồn thành mã byte và thực hiện nhiều kiểm tra tĩnh trong quy trình. Nó không liên kết nhiều như trình biên dịch C. Sự khác biệt hiệu năng thực sự là quá trình biên dịch của Java được thiết kế trong thời đại mà người ta cho rằng có thể tải toàn bộ chương trình và các phần phụ thuộc của nó vào bộ nhớ cùng một lúc thay vì phải chia nhỏ thành nhiều phần nhỏ và xử lý lại cùng một tệp hàng nghìn lần.
Peter Taylor

10

Các dự án lớn có thể mất một thời gian dài. Nó có thể là một giờ hoặc nhiều hơn cho một dự án đủ lớn. Có một vài thư viện mà tôi phải biên dịch từ nguồn trên máy tính của mình mất một thời gian rất dài - ví dụ như opencascade. Bản thân nhân Linux cũng mất khá nhiều thời gian nếu bạn phải xây dựng nó từ đầu.

Tuy nhiên, có những quá trình giống như biên dịch khác có thể mất nhiều thời gian hơn. Thiết kế mạch kỹ thuật số (cho ASIC hoặc FPGA) yêu cầu một bước địa điểm và tuyến đường. Bước vị trí và tuyến đường là nơi đặt các cổng logic riêng lẻ, flip-flop, thanh ghi, RAM và các thành phần khác được xác định cùng với định tuyến cho hệ thống dây kết nối. Phần mềm sử dụng các mô hình thời gian để xác định độ trễ cổng và định tuyến cho các vị trí có thể, so sánh các giới hạn này với các giới hạn được cung cấp bởi các ràng buộc thời gian và sau đó điều chỉnh các vị trí vị trí và đường dẫn dây để cố gắng đáp ứng các yêu cầu về thời gian. Đôi khi phần mềm thậm chí sẽ phải thay đổi kích thước cổng và thêm bộ đệm để đáp ứng thời gian. Bước này cực kỳ tính toán và có thể mất nhiều giờ hoặc thậm chí vài ngày để hoàn thành. Nó cũng không thực sự song song rất tốt. Có một thiết kế đồ họa mà tôi đã làm việc cách đây một năm, đã tiêu thụ khoảng một nửa của Virtex 6 HXT 565 FPGA (~ 300k trong số 56 nghìn LUT) và mất khoảng 7 giờ để hoàn thành địa điểm và tuyến đường. Tôi không thể tưởng tượng được sẽ mất bao lâu để chạy địa điểm và định tuyến trên một cái gì đó giống như thiết kế CPU Core i7 - có thể ít nhất là vài tuần.


4

Các câu trả lời khác đã đề cập rằng có, mã trên các dự án lớn, trong đó phương tiện lớn 500k trở lên, có thể mất thời gian đáng kể, đặc biệt là khi xây dựng từ đầu.

Điểm bổ sung là một số dự án phải được xây dựng cho nhiều môi trường đích. Khi các máy chủ lưu trữ các môi trường đó không có sẵn, việc xây dựng phải được thực hiện bằng cách biên dịch chéo, nối tiếp trên các máy mà bạn có. Điều này có thể dẫn đến thời gian xây dựng đáng kể . Đối với một dự án tôi đã làm, việc xây dựng hàng đêm sẽ mất 10 giờ. Khốn kiếp rằng bạn là người đã phá vỡ nó!

Tôi sẽ nói thêm rằng bạn sẽ không bỏ qua bất kỳ lý do nào để lãng phí thời gian. Một người chuyên nghiệp nên được lên kế hoạch công việc của họ để họ làm có một cái gì đó hữu ích để làm trong khoảng thời gian đó.


3

Một chút của cả hai. C ++ (và C ở mức độ thấp hơn) nổi tiếng với thời gian biên dịch chậm, đặc biệt là trên phần cứng thời gian. Khoảng đầu thiên niên kỷ, tôi đã làm việc trong một dự án mất khoảng 4 giờ để xây dựng do các shenanigans vĩ mô.

Ngày nay mọi thứ tốt hơn, nhưng 30 giây theo kinh nghiệm của tôi khá thấp - đặc biệt là trong các bản dựng chính thức, nơi mọi thứ cần được kiểm tra từ kiểm soát nguồn, chạy thử nghiệm đơn vị, trình cài đặt được xây dựng và mọi thứ được gửi đến SAN ở đâu đó.


2

Nó phụ thuộc vào dự án và môi trường mà nó được biên dịch. Tôi đã làm việc với các dự án C ++ mất vài phút để biên dịch (thiết lập thành nhiều dự án trong MSVS), có lẽ là đủ thời gian cho một cuộc đấu kiếm.

Nếu bạn làm việc cho một công ty lớn với cơ sở dữ liệu và mã lớn (Proctor và Gamble, Google, v.v.) hoặc cho một công ty nhỏ hoặc khởi nghiệp tập trung vào một hoặc hai sản phẩm chính rất phức tạp (ví dụ mô phỏng và kết xuất khoa học), sau đó chờ đợi một dự án lớn được biên dịch là một điều thực tế để mong đợi ngay cả trên các máy mạnh mẽ. Điều này có thể ảnh hưởng đến cách bạn phát triển và gỡ lỗi mã (cũng như tần suất bạn chọn cập nhật và hợp nhất các thay đổi thông qua phiên bản).

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.